-
Notifications
You must be signed in to change notification settings - Fork 353
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
Implement subkeys as a cw1 contract #24
Conversation
@maurolacy I sketched out my ideas on some sort of reuse of code from cw1_whitelist to add the idea of subkeys (which is allowances for native tokens, via Can you make a PR off of this to complete the work? I left some Once you make one PR implementing it, if you have better ideas on how to promote code reuse (a cleaner way that I did), please make a second PR building on it that makes those changes - feel free to reorganize code in other contracts and packages when doing this) |
OK, I'll take a look and ask you if I have any doubts. |
Also, implement SubAssign trait for Balance
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.
Nice start. Left some comments on it
I think the last two commits should be reverted (robust sub and unit test fix) but the allowance implementations look good
Please ping me when you implement execute and I will give a final review. The allowances look fine |
OK, I've done a first implementation of Please take a look. Once this is right, I'll write the unit tests. |
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.
Looks good. Just missing tests, but besides the minor cleanup I mentioned, it looks correct.
@@ -145,7 +172,7 @@ where | |||
if let Some(exp) = expires { | |||
allowance.expires = exp; | |||
} | |||
allowance.balance = allowance.balance.sub(amount.clone())?; // Fails if no tokens | |||
allowance.balance = allowance.balance.sub_saturating(amount.clone())?; // Fails if no tokens |
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 comment "fails if no tokens". Is that out of date now?
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.
Correction: that still fails if no tokens. It silently ignores underflows, but doesn't ignore a missing balance entry for that denomination. I think this is an important distinction: an admin could make a spelling mistake when trying to remove an entry, and if this fails silently, he will never be notified of the error.
Nevertheless, if you think this is not desirable / important, I'll change it to always failing silently.
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.
Related: Shouldn't denom
be case insensitive, for robustness / simplicity?
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.
Very good distinction to make (underflow vs. no denom) and I agree with it. Nice thinking.
The comment could be a little more verbose and capture that.
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.
As to case insensitive... it is case sensitive in the sdk. we could normalize both stored values and the ones we match to always be lower case before comparing. I guess that would be nice. But I'm not sure if there are issues there. Can you make an issue to add that, and we can add that later, once this is merged. And then we can maybe get some comments on the idea. I am not completely sure about that one.
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.
Me neither... I'll create the issue.
I'm glad I figured it out. I must say in the name of truth that it was mostly based on logic and deductions, as I still lack detailed knowledge of the platform and the SDK. |
Please add an issue to https://github.com/CosmWasm/docs2 for all info you would like to have readily accessible when first wirting a contract. We are planning/starting an overhaul of the docs site and input from people just starting with CosmWasm is invaluable. You an make a new issue or add some thoughts here: CosmWasm/docs-deprecated#5 |
For me, the most "difficult" part was in some cases to figure out what NOT to do (i. e. what was not necessary). To be fair, this is probably related to my way of approaching things, as I'm no fan of reading lot of docs when starting with something new, and prefer to gain a big picture gradually. Starting from the details, so to speak. Regarding the "complexities": By example, the fact that for relaying the messages it was enough to set the I must say that the examples are very good, and were very useful in general. I'll probably elaborate on this in the issue later, but I would say that some short documents, even diagrams, with the aim to gain a big picture quickly, particularly of the interactions and responsibilities of the different parts and frameworks, would be very useful for would-be contract writers. Finally: these are not simple matters. I mean, the API and the SDK can make writing functional / useful contracts a relatively easy task, but the functionality itself must be very well thought of, as there are many corner cases, this is a delicate area in terms of security, money and finances are involved, etc., 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.
Very well done @maurolacy I like the tests.
I will merge this in now. Thank you for completing this contract. I look forward to deploying it on our next testnets.
} | ||
); | ||
|
||
// Add to spender4 (new account) (expires = Some) |
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.
Nicely covering all the use cases.
It actually seems the zip
above did exactly what you wanted it to do.
but setup_test_case
needs better rustdoc, so this is expected behavior
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.
I think it's related to the comment above. I'll clarify the code with better naming / comments.
allowance, | ||
Allowance { | ||
balance: Balance(vec![ | ||
coin(amount1 / 2 + (amount1 & 1), denom1), |
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.
I would usually use + (amount1 % 2)
rather than + (amount 1 & 1)
but they produce the same result.
I guess you are more used to embedded systems than I am.
Oops, I realized I had some change requests above, after I merged. |
Sure, I was planning to finish those two remaining tests tomorrow morning anyway. Sorry to commit / push partial stuff. I'm just used to working that way. I can change it if it's a burden. |
No, it is great. Please keep pushing. Two issues.. it is late and I was trigger happy on a merge. And two, I opened this PR, otherwise I would have waited for you to take it out of draft mode before merging. Generally, open a draft PR when starting something and mark "ready for review" when you feel it is good to merge if approved. |
This idea was thrown around Summer 2019.
Basically an account that can authorize arbitrary external accounts to spend some limited amount of tokens from it. And in theory perform other actions (like staking).
This implements subkey controls over the native
Bank::SendMsg
action as part of a cw1-proxy contract.