-
-
Notifications
You must be signed in to change notification settings - Fork 819
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
VIP: native asset types #3716
Comments
Overall I like this idea very much. But I have to admit that I had to read the specs multiple times to understand the semantics of the "intrinsic sign" correctly. I think the word T = vyper.TypeVar("uint256")
totalSupply: public(Resource[T])
balanceOf: public(HashMap[address, Resource[vyper.type(self.totalSupply)])
def transfer(to: address, amount: uint256):
transfer_resource(self.totalSupply, self.balanceOf[msg.sender], self.balanceOf[to], amount)
def mint(owner: address, amount: uint256):
create_resource(self.totalSupply, empty(address), self.balanceOf[owner], amount)
def burn(owner: address, amount: uint256):
destroy_resource(self.totalSupply, self.balanceOf[owner], empty(address), amount) So the functions would be like: transfer_resource(resource: Resource[T], resource_origin: HashMap[address, Resource[vyper.type(resource)]], resource_destination: HashMap[address, Resource[vyper.type(resource)]], resource_amount: uint256)
create_resource(resource: Resource[T], resource_origin: address=empty(address), resource_destination: HashMap[address, Resource[vyper.type(resource)]], resource_amount: uint256)
destroy_resource(resource: Resource[T], resource_origin: HashMap[address, Resource[vyper.type(resource)]], resource_destination: address=empty(address), resource_amount: uint256) We might want to have an I personally like |
i have a slight preference for "asset"- related terminology. "resource" sounds more like filehandles or linear types. i think maybe the key insight from the "theory" of double-entry accounting being applied here is that assets are never created or destroyed, only moved -- and the way it is able to work is because some accounts have opposite intrinsic sign than others. so |
recommended reading for those unfamiliar with the debits/credits terminology: https://en.wikipedia.org/wiki/Debits_and_credits |
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
Direct feedback: the "intrinsic sign" is very hard to understand, and using operators seems quite likely to be overlooked when auditing. Would at least suggest using some sort of built-in enum relating to that new type e.g.: Further feel like it doesn't have to be a language-level built-in type with some more generic features made available, it could be implemented as a user-generated type |
yea, i agree that the intrinsic sign is not super intuitive as an API. i think a better API is to have two separate types transfer_from(dst: Asset[T], src: Asset[T], T)
mint_from(dst: Asset[T], src: DAsset[T], T)
burn_from(dst: DAsset[T], src: Asset[T], T) these all do the same thing(!), debit
it would be neat if it could be implemented with pure vyper :). but even if it can't, i don't think that should be a blocker for inclusion in the language. safe accounting is important enough to smart contract programming that i think it should have first-class support in a smart contract language! if at a later date vyper does support generics (with the necessary intrinsics/protocols), it could maybe be reimplemented in pure vyper as part of the standard library, but i don't think we need to block the feature waiting on generics. |
Wanted to add my off-github comment here: Good idea but seems very limited in use case. Also forces you to have a storage variable for every total which may not be desirable e.g. if you want to use this to track token deposits you now need an |
Wanted to stick a comment from the other day in here, but I think the best use cases for this type of thing is managing external assets (e.g. ERC4626), not ERC20 ledger values. So like, associating a storage variable with a particular asset type in such a way that they don't get out of sync (a common source of bugs like inflation attacks, improper asset controls, etc.) One nice thing might even to be able say like |
Simple Summary
bring new types to vyper which safely model assets, natively
Motivation
accounting is hard. instead of assets being represented by raw numbers as they currently are, add a special kind of asset type which is more constrained. this removes the possibility for rounding errors and will increase clarity of user code.
this new type enforces the invariant that each action to the ledger has an equal and opposite reaction. in code- terms, it un-denormalizes code, increases DRYness and reduces the potential for accounting bugs (ex. rounding errors, missed actions).
notes:
Specification
add a new parametrizable type,
Asset
to vyper.Asset
takes two type parameters, the subtype and an "intrinsic sign", which basically just corresponds to whether the account is debit- or credit- normal.Asset
cannot be assigned to directly, but can only be modified through the builtinmove_from()
method. (if you squint closely,move_from()
is basically a single, balancing debit+credit).example:
tbd:
Asset
+/-
syntax might look a little funky to programmers, maybeAsset
vsNegativeAsset
are more intuitivemove_from
could be unintuitive when the source and destination accounts have opposite intrinsic signs. if this is the case, maybe additional methods likemint_to(src: Asset, dst: NegativeAsset)
andburn_from(src: Asset, dst: NegativeAsset)
could potentially be considered. the usage ofmove_from
in the abovemint()
function would not be allowed and it would instead be written asBackwards Compatibility
no breaking changes
References
#1277
https://en.wikipedia.org/wiki/Debits_and_credits
Copyright
Copyright and related rights waived via CC0
The text was updated successfully, but these errors were encountered: