Skip to content

Commit

Permalink
fix(iota-framework): check already minted supply for CoinManager (#…
Browse files Browse the repository at this point in the history
…3845)

* refactor(iota-types): remove capped_coin

* fix(iota-framework): fixed maximum supply check in the `iota::coin_manager` module

* feat(iota-framework-snapshot): update the snapshot

* fix(iota-swarm-config): update the snapshot

* fix(iota-graphql-e2e-tests): update the snapshots

* fix(iota-framework): clean `coin_manager_tests.move`
  • Loading branch information
valeriyr authored Nov 4, 2024
1 parent ab7bb45 commit 645b6b9
Show file tree
Hide file tree
Showing 83 changed files with 2,678 additions and 2,334 deletions.
Binary file not shown.
2 changes: 1 addition & 1 deletion crates/iota-framework-snapshot/manifest.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"1": {
"git_revision": "f1f6c498eb44",
"git_revision": "cfa0f7babbc4",
"package_ids": [
"0x0000000000000000000000000000000000000000000000000000000000000001",
"0x0000000000000000000000000000000000000000000000000000000000000002",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,23 @@ module iota::coin_manager {
use iota::balance::{Balance, Supply};
use iota::dynamic_field as df;

/// The error returned when the maximum supply reached.
/// The error returned when the maximum supply reached
const EMaximumSupplyReached: u64 = 0;

/// The error returned if a attempt is made to change the maximum supply after setting it
const EMaximumSupplyAlreadySet: u64 = 1;

/// The error returned if a attempt is made to change the maximum supply that is lower than the total supply
const EMaximumSupplyLowerThanTotalSupply: u64 = 2;

/// The error returned if additional metadata already exists and you try to overwrite
const EAdditionalMetadataAlreadyExists: u64 = 2;
const EAdditionalMetadataAlreadyExists: u64 = 3;

/// The error returned if you try to edit nonexisting additional metadata
const EAdditionalMetadataDoesNotExist: u64 = 3;
const EAdditionalMetadataDoesNotExist: u64 = 4;

/// The error returned if you try to edit immutable metadata
const ENoMutableMetadata: u64 = 4;
const ENoMutableMetadata: u64 = 5;

/// Holds all related objects to a Coin in a convenient shared function
public struct CoinManager<phantom T> has key, store {
Expand Down Expand Up @@ -227,6 +230,7 @@ module iota::coin_manager {
maximum_supply: u64
) {
assert!(option::is_none(&manager.maximum_supply), EMaximumSupplyAlreadySet);
assert!(total_supply(manager) <= maximum_supply, EMaximumSupplyLowerThanTotalSupply);
option::fill(&mut manager.maximum_supply, maximum_supply);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,18 @@ module iota::coin_manager_tests {
scenario.ctx(),
);


let (cmcap, metacap, mut wrapper) = coin_manager::new(cap, meta, scenario.ctx());

assert!(wrapper.decimals() == 0, 0);
assert!(wrapper.decimals() == 0);

// We should start out with a Supply of 0.
assert!(wrapper.total_supply() == 0, 0);
assert!(wrapper.total_supply() == 0);

// Mint some coin!
cmcap.mint_and_transfer(&mut wrapper, 10, sender, scenario.ctx());

// We should now have a Supply of 10.
assert!(wrapper.total_supply() == 10, 0);
assert!(wrapper.total_supply() == 10);

// No maximum supply set, so we can do this again!
cmcap.mint_and_transfer(&mut wrapper, 10, sender, scenario.ctx());
Expand Down Expand Up @@ -75,16 +74,16 @@ module iota::coin_manager_tests {
scenario.ctx(),
);

assert!(wrapper.decimals() == 0, 0);
assert!(wrapper.decimals() == 0);

// We should start out with a Supply of 0.
assert!(wrapper.total_supply() == 0, 0);
assert!(wrapper.total_supply() == 0);

// Mint some coin!
cmcap.mint_and_transfer(&mut wrapper, 10, sender, scenario.ctx());

// We should now have a Supply of 10.
assert!(wrapper.total_supply() == 10, 0);
assert!(wrapper.total_supply() == 10);

// No maximum supply set, so we can do this again!
cmcap.mint_and_transfer(&mut wrapper, 10, sender, scenario.ctx());
Expand All @@ -98,7 +97,7 @@ module iota::coin_manager_tests {

#[test]
#[expected_failure(abort_code = coin_manager::EMaximumSupplyReached)]
fun test_max_supply() {
fun test_max_supply_higher_that_total() {
let sender = @0xA;
let mut scenario = test_scenario::begin(sender);
let witness = COIN_MANAGER_TESTS{};
Expand All @@ -114,24 +113,106 @@ module iota::coin_manager_tests {
scenario.ctx(),
);


let (cmcap, metacap, mut wrapper) = coin_manager::new(cap, meta, scenario.ctx());

// We should start out with a Supply of 0.
assert!(wrapper.total_supply() == 0, 0);
assert!(wrapper.total_supply() == 0);

// Enforce a Max Supply
// Enforce a Max Supply.
cmcap.enforce_maximum_supply(&mut wrapper, 10);

// Mint some coin!
cmcap.mint_and_transfer(&mut wrapper, 10, sender, scenario.ctx());

// We should now have a Supply of 10.
assert!(wrapper.total_supply() == 10, 0);
assert!(wrapper.total_supply() == 10);

// This should fail.
cmcap.mint_and_transfer(&mut wrapper, 1, sender, scenario.ctx());

transfer::public_transfer(cmcap, scenario.ctx().sender());
metacap.renounce_metadata_ownership(&mut wrapper);

transfer::public_share_object(wrapper);

scenario.end();
}

#[test]
#[expected_failure(abort_code = coin_manager::EMaximumSupplyReached)]
fun test_max_supply_equals_total() {
let sender = @0xA;
let mut scenario = test_scenario::begin(sender);
let witness = COIN_MANAGER_TESTS{};

// Create a `Coin`.
let (cap, meta) = coin::create_currency(
witness,
0,
b"TEST",
b"TEST",
b"TEST",
option::none(),
scenario.ctx(),
);

let (cmcap, metacap, mut wrapper) = coin_manager::new(cap, meta, scenario.ctx());

// We should start out with a Supply of 0.
assert!(wrapper.total_supply() == 0);

// Mint some coin!
cmcap.mint_and_transfer(&mut wrapper, 10, sender, scenario.ctx());

// We should now have a Supply of 10.
assert!(wrapper.total_supply() == 10);

// Enforce a Max Supply.
cmcap.enforce_maximum_supply(&mut wrapper, 10);

// This should fail
// This should fail.
cmcap.mint_and_transfer(&mut wrapper, 1, sender, scenario.ctx());

transfer::public_transfer(cmcap, scenario.ctx().sender());
metacap.renounce_metadata_ownership(&mut wrapper);

transfer::public_share_object(wrapper);

scenario.end();
}

#[test]
#[expected_failure(abort_code = coin_manager::EMaximumSupplyLowerThanTotalSupply)]
fun test_max_supply_lower_than_total() {
let sender = @0xA;
let mut scenario = test_scenario::begin(sender);
let witness = COIN_MANAGER_TESTS{};

// Create a `Coin`.
let (cap, meta) = coin::create_currency(
witness,
0,
b"TEST",
b"TEST",
b"TEST",
option::none(),
scenario.ctx(),
);

let (cmcap, metacap, mut wrapper) = coin_manager::new(cap, meta, scenario.ctx());

// We should start out with a Supply of 0.
assert!(wrapper.total_supply() == 0);

// Mint some coin!
cmcap.mint_and_transfer(&mut wrapper, 10, sender, scenario.ctx());

// We should now have a Supply of 10.
assert!(wrapper.total_supply() == 10);

// Update the maximum supply to be lower than the total supply, this should not be allowed.
cmcap.enforce_maximum_supply(&mut wrapper, 9);

transfer::public_transfer(cmcap, scenario.ctx().sender());
metacap.renounce_metadata_ownership(&mut wrapper);

Expand All @@ -158,13 +239,12 @@ module iota::coin_manager_tests {
scenario.ctx(),
);


let (cmcap, metacap, mut wrapper) = coin_manager::new(cap, meta, scenario.ctx());

// Enforce a Max Supply
// Enforce a Max Supply.
cmcap.enforce_maximum_supply(&mut wrapper, 10);

// Update it, this should not be allowed
// Update it, this should not be allowed.
cmcap.enforce_maximum_supply(&mut wrapper, 20);

transfer::public_transfer(cmcap, scenario.ctx().sender());
Expand Down Expand Up @@ -192,41 +272,40 @@ module iota::coin_manager_tests {
scenario.ctx(),
);


let (cmcap, metacap, mut wrapper) = coin_manager::new(cap, meta, scenario.ctx());

// We should start out with a Supply of 0.
assert!(wrapper.total_supply() == 0, 0);
assert!(wrapper.total_supply() == 0);

// Enforce a Max Supply
// Enforce a Max Supply.
cmcap.enforce_maximum_supply(&mut wrapper, 10);

// Mint some coin!
cmcap.mint_and_transfer(&mut wrapper, 5, sender, scenario.ctx());

// We should now have a Supply of 5.
assert!(wrapper.total_supply() == 5, 0);
assert!(wrapper.total_supply() == 5);

// We should now have a Max Supply of 10.
assert!(wrapper.maximum_supply() == 10, 0);
assert!(wrapper.maximum_supply() == 10);

// The coin is not immutable right now, we still have a `CoinManagerCap`
assert!(!wrapper.supply_is_immutable(), 1);
assert!(!wrapper.metadata_is_immutable(), 1);
// The coin is not immutable right now, we still have a `CoinManagerCap`.
assert!(!wrapper.supply_is_immutable());
assert!(!wrapper.metadata_is_immutable());

// Lets turn it immutable!
cmcap.renounce_treasury_ownership(&mut wrapper);

// The coin should be immutable right now
assert!(wrapper.supply_is_immutable(), 2);
// But metadata should still be mutable
assert!(!wrapper.metadata_is_immutable(), 1);
// The coin should be immutable right now.
assert!(wrapper.supply_is_immutable());
// But metadata should still be mutable.
assert!(!wrapper.metadata_is_immutable());

// We should now have a Max Supply of 5, due to renouncing of ownership.
assert!(wrapper.maximum_supply() == 5, 3);
assert!(wrapper.maximum_supply() == 5);

metacap.renounce_metadata_ownership(&mut wrapper);
assert!(wrapper.metadata_is_immutable(), 1);
assert!(wrapper.metadata_is_immutable());

transfer::public_share_object(wrapper);
scenario.end();
Expand All @@ -249,7 +328,6 @@ module iota::coin_manager_tests {
scenario.ctx(),
);


let (cmcap, metacap, mut wrapper) = coin_manager::new(cap, meta, scenario.ctx());

let bonus = BonusMetadata {
Expand All @@ -259,7 +337,7 @@ module iota::coin_manager_tests {

metacap.add_additional_metadata(&mut wrapper, bonus);

assert!(!wrapper.additional_metadata<COIN_MANAGER_TESTS, BonusMetadata>().is_amazing, 0);
assert!(!wrapper.additional_metadata<COIN_MANAGER_TESTS, BonusMetadata>().is_amazing);

let bonus2 = BonusMetadata {
website: url::new_unsafe(string(b"https://iota.org")),
Expand All @@ -270,7 +348,7 @@ module iota::coin_manager_tests {

let BonusMetadata { website: _, is_amazing: _ } = oldmeta;

assert!(wrapper.additional_metadata<COIN_MANAGER_TESTS, BonusMetadata>().is_amazing, 0);
assert!(wrapper.additional_metadata<COIN_MANAGER_TESTS, BonusMetadata>().is_amazing);

cmcap.renounce_treasury_ownership(&mut wrapper);
metacap.renounce_metadata_ownership(&mut wrapper);
Expand All @@ -296,19 +374,18 @@ module iota::coin_manager_tests {
scenario.ctx(),
);


transfer::public_freeze_object(meta);
test_scenario::next_tx(&mut scenario, sender);

let immeta = test_scenario::take_immutable<CoinMetadata<COIN_MANAGER_TESTS>>(&scenario);
let (cmcap, mut wrapper) = coin_manager::new_with_immutable_metadata(cap, &immeta, scenario.ctx());

assert!(wrapper.metadata_is_immutable(), 0);
assert!(wrapper.metadata_is_immutable());

assert!(wrapper.decimals() == 0, 0);
assert!(wrapper.decimals() == 0);

// We should start out with a Supply of 0.
assert!(wrapper.total_supply() == 0, 0);
assert!(wrapper.total_supply() == 0);

// Mint some coin!
cmcap.mint_and_transfer(&mut wrapper, 10, sender, scenario.ctx());
Expand All @@ -319,4 +396,4 @@ module iota::coin_manager_tests {

scenario.end();
}
}
}
Binary file modified crates/iota-framework/packages_compiled/iota-framework
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,20 @@ Response: {
"data": {
"availableRange": {
"first": {
"digest": "DbuejNSgvHrPUDyucKV46j9kdT8f5VV78PWjLzV41yVw",
"digest": "Ap4ddWHXeYVMSMcf8cQT9j7WUM1rGKw7rG3Q8rpsuaUd",
"sequenceNumber": 0
},
"last": {
"digest": "DbuejNSgvHrPUDyucKV46j9kdT8f5VV78PWjLzV41yVw",
"digest": "Ap4ddWHXeYVMSMcf8cQT9j7WUM1rGKw7rG3Q8rpsuaUd",
"sequenceNumber": 0
}
},
"first": {
"digest": "DbuejNSgvHrPUDyucKV46j9kdT8f5VV78PWjLzV41yVw",
"digest": "Ap4ddWHXeYVMSMcf8cQT9j7WUM1rGKw7rG3Q8rpsuaUd",
"sequenceNumber": 0
},
"last": {
"digest": "DbuejNSgvHrPUDyucKV46j9kdT8f5VV78PWjLzV41yVw",
"digest": "Ap4ddWHXeYVMSMcf8cQT9j7WUM1rGKw7rG3Q8rpsuaUd",
"sequenceNumber": 0
}
}
Expand All @@ -39,20 +39,20 @@ Response: {
"data": {
"availableRange": {
"first": {
"digest": "DbuejNSgvHrPUDyucKV46j9kdT8f5VV78PWjLzV41yVw",
"digest": "Ap4ddWHXeYVMSMcf8cQT9j7WUM1rGKw7rG3Q8rpsuaUd",
"sequenceNumber": 0
},
"last": {
"digest": "3GN2xF2YRGs1wwh1BuaWexjsfYjqcRrxut4hCmKudWdq",
"digest": "6SSpR1JWujKRTEB844us1vSSxjpD3RADCZ6HujXWx9a1",
"sequenceNumber": 2
}
},
"first": {
"digest": "DbuejNSgvHrPUDyucKV46j9kdT8f5VV78PWjLzV41yVw",
"digest": "Ap4ddWHXeYVMSMcf8cQT9j7WUM1rGKw7rG3Q8rpsuaUd",
"sequenceNumber": 0
},
"last": {
"digest": "3GN2xF2YRGs1wwh1BuaWexjsfYjqcRrxut4hCmKudWdq",
"digest": "6SSpR1JWujKRTEB844us1vSSxjpD3RADCZ6HujXWx9a1",
"sequenceNumber": 2
}
}
Expand Down
Loading

0 comments on commit 645b6b9

Please sign in to comment.