-
Notifications
You must be signed in to change notification settings - Fork 11.6k
[sui framework] add marker dynamic field to regulated coin metadata #19852
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: main
Are you sure you want to change the base?
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
3 Skipped Deployments
|
/// Return None if T was created at an epoch before `REGULATED_MARKER_START_EPOCH`. Before | ||
/// this epoch, it was not possible to distinguish between regulated and unregulated currencies by | ||
/// looking at the metadata. | ||
public fun is_regulated_currency<T>(metadata: &CoinMetadata<T>, ctx: &mut TxContext): Option<bool> { |
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 don't think context should be mutable here. Can't think of a single scenario where we'd find it useful.
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.
Good point + I'm surprised there's no linter or compiler warning to yell at me. Is this because it would be too noisy in the case that folks do this for upgrade friendliness, and it's too hard to distinguish between that case and this one?
}); | ||
if (ctx.epoch() >= REGULATED_MARKER_START_EPOCH) { | ||
dynamic_field::add(&mut metadata.id, RegulatedMarker {}, allow_global_pause); | ||
assert!(is_regulated_currency(&metadata, ctx).extract()); |
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.
What is the reason behind this assert? May be missing something, but we make this assertion true in the line above, no?
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.
Leftover debugging code; will remove
coin_metadata_object: object::id(&metadata), | ||
deny_cap_object: object::id(&deny_cap), | ||
}); | ||
if (ctx.epoch() >= REGULATED_MARKER_START_EPOCH) { |
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.
Why do we need to do epoch checks on creation / migration?
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's a fair question--I guess there's no harm to adding the marker right away. I will do that instead.
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.
Reworked a lot of stuff based on this--now using an enum that gets added to every metadata (not jus the regulated one), and no more epoch checks. Thanks!
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.
Love that way more, feels cleaner too!
Generally, this looks good to me. If we're definitely aligned on having this on the framework and not waiting for metadata V2!
cab8bc1
to
cf92358
Compare
false, | ||
ctx, | ||
); | ||
assert!(coin::is_regulated_currency(&metadata).is_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.
Blind (untested) comment but receiver syntax should work, no? They are both in the coin module (can be applied to all tests / calls).
assert!(coin::is_regulated_currency(&metadata).is_some()); | |
assert!(metadata.is_regulated_currency().is_some()); |
@sblackshear should we also allow existing regulated coins to migrate their metadata (add the marker) by presenting the DenyCapV2? |
I looked into this, but I don't think it's easy to do in a foolproof way because of the supported |
cf92358
to
53fcfee
Compare
53fcfee
to
f289364
Compare
|
||
/// A dynamic field key added to `CoinMetadata` objects created after protocol version 63. | ||
/// This is bound to a `RegulatedInfo` enum | ||
public struct RegulatedMarker has copy, drop, store {} |
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.
nit
public struct RegulatedMarker has copy, drop, store {} | |
public struct RegulatedMarker() has copy, drop, store; |
// b"Kill switch was not allowed at the creation of the DenyCapV2"; | ||
const EGlobalPauseNotAllowed: u64 = 3; | ||
|
||
|
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.
|
||
/// Return Some(true) if `T` is a regulated currency that allows global pause, Some(false) if it is | ||
/// regulated but does not allow global pause, or is an ordinary currency. | ||
/// Return None if T was created at an epoch before `REGULATED_MARKER_START_EPOCH`. Before |
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.
What is REGULATED_MARKER_START_EPOCH?
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.
Good call--this is tale + I will fix
/// An ordinary coin that does not support a denylist or global pause | ||
Ordinary, | ||
/// A regulated coin that supports a denylist, and (maybe) global paus | ||
Regulated { allow_global_pause: bool} |
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.
What if we did something like
Regulated { allow_global_pause: bool} | |
Regulated { deny_cap: ID } |
which points to the DenyCapV2
. Obviously some issues if the object is wrapped/deleted, but the flag allow_global_pause
cannot be modified after creation, so it is fine to look at the last time the DenyCap
existed.
My goal here is to allow existing coins (at least regulated ones) to add their RegulatedInfo
after the fact.
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 intention of this change is to allow Move code to special-case regulated coins (e.g., DEX pool creation, which typically already asks for CoinMetadata
to get the decimals
). If the Move code wants to treat global pause coins differently, it needs a boolean, not a pointer.
Would be fine adding the deny cap ID as additional metadata--more info seems better for sure
f289364
to
244b25b
Compare
244b25b
to
3796ee3
Compare
coin_metadata_object: object::id(&metadata), | ||
deny_cap_object: object::id(&deny_cap), | ||
}); | ||
dynamic_field::add( |
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.
Since we're allowing both V1 and V2 denycaps, do we really need to store the id of the deny_cap in the marker? It can get invalid the moment you migrate V1 to V2.
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.
Yeah that's fair, the migration is giant PiTA that basically makes everything potentially inconsistent except for marking the metadata as regulated/not. Will revert to that
dynamic_field::add( | ||
&mut metadata.id, | ||
RegulatedMarker(), | ||
RegulatedInfo::Regulated { allow_global_pause: false, deny_cap_id: object::id(&deny_cap) } |
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.
allow_global_pause
can end up converted to true when migrating to v2, while the metadata wouldn't reflect. Isn't this a small vulnerability for protocols who might trust this field?
Add functions to determine whether whether a coin is regulated + whether it supports global pause or not by inspecting the metadata. Handy for use-cases that want to special case these coins.
3796ee3
to
b940acf
Compare
This PR is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days. |
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.
lgtm
Add functions to determine whether whether a coin is regulated + whether it supports global pause or not by inspecting the metadata. Handy for use-cases that want to special case these coins.