-
Notifications
You must be signed in to change notification settings - Fork 30
Update to CEP-18 Standard #97
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
/// the tokens on behalf of the caller. | ||
/// The `inc_by` is the amount by which the allowance should be increased. | ||
fn increase_allowance(&mut self, spender: Key, inc_by: U256); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi,
I would add mint
and burn
even if they are behind a configuration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most of the times during the development having mint
and burn
just made things unnecessarily complicated, and is not useful at all, as burning and minting logic is different from project to project. I'm strongly against having them in the standard.
Having it in casper-ecosystem
's implementation with modalities is still good idea as it serves as a standalone token with basic governance. But these doesn't have to be part of the standard.
/// Spender does not have enough allowance approved. | ||
InsufficientAllowance = 60002, | ||
/// The user cannot target themselves. | ||
CannotTargetSelfUser = 60003, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right now this first errors in current implmentation are
pub enum Cep18Error {
InvalidContext = 60000,
InsufficientBalance = 60001,
InsufficientAllowance = 60002,
Overflow = 60003,
PackageHashMissing = 60004,
etc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The errors I propose are implementation-agnostic and comes from the logic of the token mechanics. Things like InvalidContext
are framework-releated and shouldn't be here. In the casper-ecosystem/cep18
implementation, you have errors that doesn't happen in Odra's implementation and vice versa.
|
||
The CEP-18 token implementations are available under the following links: | ||
- https://github.com/casper-ecosystem/cep18 | ||
- https://github.com/odradev/odra/blob/HEAD/modules/src/cep18_token.rs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems to me strange to establish an interface using Casper Key type and having an implementation that differs by implementing the wrapper Address like
pub fn transfer(&mut self, recipient: &Address, amount: &U256) {
It's a small difference but it kind of defeats the intention of this document somehow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Odra's Address serializes and deserializes to Key
, but only supports Key's variants that makes sense. You can think of it as a implementation detail.
From Odra's codebase
impl CLTyped for Address {
fn cl_type() -> CLType {
CLType::Key
}
}
impl ToBytes for Address {
fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> {
Key::from(*self).to_bytes()
}
fn serialized_length(&self) -> usize {
Key::from(*self).serialized_length()
}
}
impl FromBytes for Address {
fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> {
let (key, remainder) = Key::from_bytes(bytes)?;
let address = match key {
Key::Account(account_hash) => Address::Account(account_hash),
Key::Hash(raw_contract_package_hash) => {
Address::Contract(ContractPackageHash::new(raw_contract_package_hash))
}
_ => return Err(bytesrepr::Error::Formatting)
};
Ok((address, remainder))
}
}
While casper-ecosystem
implementation actually allows for all kinds of Key types, but it still uses only AccountHash and PackageHash (and EntityAddr, but this most likely will never be turned on, more here: casper-network/casper-node#4511). Other kinds of Keys simply doesn't make any sense to be recipient of tokens, as they would be unrecoverable.
Given all the above, I think Key
as address is technically the right choice for the standard, from the lack of better choice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gRoussac thanks for reviewing
/// the tokens on behalf of the caller. | ||
/// The `inc_by` is the amount by which the allowance should be increased. | ||
fn increase_allowance(&mut self, spender: Key, inc_by: U256); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most of the times during the development having mint
and burn
just made things unnecessarily complicated, and is not useful at all, as burning and minting logic is different from project to project. I'm strongly against having them in the standard.
Having it in casper-ecosystem
's implementation with modalities is still good idea as it serves as a standalone token with basic governance. But these doesn't have to be part of the standard.
/// Spender does not have enough allowance approved. | ||
InsufficientAllowance = 60002, | ||
/// The user cannot target themselves. | ||
CannotTargetSelfUser = 60003, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The errors I propose are implementation-agnostic and comes from the logic of the token mechanics. Things like InvalidContext
are framework-releated and shouldn't be here. In the casper-ecosystem/cep18
implementation, you have errors that doesn't happen in Odra's implementation and vice versa.
|
||
The CEP-18 token implementations are available under the following links: | ||
- https://github.com/casper-ecosystem/cep18 | ||
- https://github.com/odradev/odra/blob/HEAD/modules/src/cep18_token.rs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Odra's Address serializes and deserializes to Key
, but only supports Key's variants that makes sense. You can think of it as a implementation detail.
From Odra's codebase
impl CLTyped for Address {
fn cl_type() -> CLType {
CLType::Key
}
}
impl ToBytes for Address {
fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> {
Key::from(*self).to_bytes()
}
fn serialized_length(&self) -> usize {
Key::from(*self).serialized_length()
}
}
impl FromBytes for Address {
fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> {
let (key, remainder) = Key::from_bytes(bytes)?;
let address = match key {
Key::Account(account_hash) => Address::Account(account_hash),
Key::Hash(raw_contract_package_hash) => {
Address::Contract(ContractPackageHash::new(raw_contract_package_hash))
}
_ => return Err(bytesrepr::Error::Formatting)
};
Ok((address, remainder))
}
}
While casper-ecosystem
implementation actually allows for all kinds of Key types, but it still uses only AccountHash and PackageHash (and EntityAddr, but this most likely will never be turned on, more here: casper-network/casper-node#4511). Other kinds of Keys simply doesn't make any sense to be recipient of tokens, as they would be unrecoverable.
Given all the above, I think Key
as address is technically the right choice for the standard, from the lack of better choice.
rendered
Following update is the conclusion of all the conversations about token standards.
This is a more detailed and cleaned up version of the CEP-18 standard.