Skip to content

Commit

Permalink
Merge pull request boscore#7 from EOSIO/retire-tokens
Browse files Browse the repository at this point in the history
retire tokens boscore#6
  • Loading branch information
larryk85 authored Jul 10, 2018
2 parents 90f8e38 + a8ac830 commit e96f801
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 1 deletion.
11 changes: 11 additions & 0 deletions eosio.token/abi/eosio.token.abi
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@
{"name":"quantity", "type":"asset"},
{"name":"memo", "type":"string"}
]
},{
"name": "retire",
"base": "",
"fields": [
{"name":"quantity", "type":"asset"},
{"name":"memo", "type":"string"}
]
},{
"name": "close",
"base": "",
Expand Down Expand Up @@ -59,6 +66,10 @@
"name": "issue",
"type": "issue",
"ricardian_contract": ""
},{
"name": "retire",
"type": "retire",
"ricardian_contract": ""
}, {
"name": "create",
"type": "create",
Expand Down
2 changes: 2 additions & 0 deletions eosio.token/include/eosio.token/eosio.token.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ namespace eosio {

void issue( account_name to, asset quantity, string memo );

void retire( asset quantity, string memo );

void transfer( account_name from,
account_name to,
asset quantity,
Expand Down
27 changes: 26 additions & 1 deletion eosio.token/src/eosio.token.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,31 @@ void token::issue( account_name to, asset quantity, string memo )
}
}

void token::retire( asset quantity, string memo )
{
auto sym = quantity.symbol;
eosio_assert( sym.is_valid(), "invalid symbol name" );
eosio_assert( memo.size() <= 256, "memo has more than 256 bytes" );

auto sym_name = sym.name();
stats statstable( _self, sym_name );
auto existing = statstable.find( sym_name );
eosio_assert( existing != statstable.end(), "token with symbol does not exist" );
const auto& st = *existing;

require_auth( st.issuer );
eosio_assert( quantity.is_valid(), "invalid quantity" );
eosio_assert( quantity.amount > 0, "must retire positive quantity" );

eosio_assert( quantity.symbol == st.supply.symbol, "symbol precision mismatch" );

statstable.modify( st, 0, [&]( auto& s ) {
s.supply -= quantity;
});

sub_balance( st.issuer, quantity );
}

void token::transfer( account_name from,
account_name to,
asset quantity,
Expand Down Expand Up @@ -121,4 +146,4 @@ void token::close( account_name owner, symbol_type symbol ) {

} /// namespace eosio

EOSIO_ABI( eosio::token, (create)(issue)(transfer)(close) )
EOSIO_ABI( eosio::token, (create)(issue)(transfer)(close)(retire) )
65 changes: 65 additions & 0 deletions tests/eosio.token_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,14 @@ class eosio_token_tester : public tester {
);
}

action_result retire( account_name issuer, asset quantity, string memo ) {
return push_action( issuer, N(retire), mvo()
( "quantity", quantity)
( "memo", memo)
);

}

action_result transfer( account_name from,
account_name to,
asset quantity,
Expand Down Expand Up @@ -225,6 +233,63 @@ BOOST_FIXTURE_TEST_CASE( issue_tests, eosio_token_tester ) try {

} FC_LOG_AND_RETHROW()

BOOST_FIXTURE_TEST_CASE( retire_tests, eosio_token_tester ) try {

auto token = create( N(alice), asset::from_string("1000.000 TKN"));
produce_blocks(1);

BOOST_REQUIRE_EQUAL( success(), issue( N(alice), N(alice), asset::from_string("500.000 TKN"), "hola" ) );

auto stats = get_stats("3,TKN");
REQUIRE_MATCHING_OBJECT( stats, mvo()
("supply", "500.000 TKN")
("max_supply", "1000.000 TKN")
("issuer", "alice")
);

auto alice_balance = get_account(N(alice), "3,TKN");
REQUIRE_MATCHING_OBJECT( alice_balance, mvo()
("balance", "500.000 TKN")
);

BOOST_REQUIRE_EQUAL( success(), retire( N(alice), asset::from_string("200.000 TKN"), "hola" ) );
stats = get_stats("3,TKN");
REQUIRE_MATCHING_OBJECT( stats, mvo()
("supply", "300.000 TKN")
("max_supply", "1000.000 TKN")
("issuer", "alice")
);
alice_balance = get_account(N(alice), "3,TKN");
REQUIRE_MATCHING_OBJECT( alice_balance, mvo()
("balance", "300.000 TKN")
);

//should fail to retire more than current supply
BOOST_REQUIRE_EQUAL( wasm_assert_msg("overdrawn balance"), retire( N(alice), asset::from_string("500.000 TKN"), "hola" ) );

BOOST_REQUIRE_EQUAL( success(), transfer( N(alice), N(bob), asset::from_string("200.000 TKN"), "hola" ) );
//should fail to retire since tokens are not on the issuer's balance
BOOST_REQUIRE_EQUAL( wasm_assert_msg("overdrawn balance"), retire( N(alice), asset::from_string("300.000 TKN"), "hola" ) );
//transfer tokens back
BOOST_REQUIRE_EQUAL( success(), transfer( N(bob), N(alice), asset::from_string("200.000 TKN"), "hola" ) );

BOOST_REQUIRE_EQUAL( success(), retire( N(alice), asset::from_string("300.000 TKN"), "hola" ) );
stats = get_stats("3,TKN");
REQUIRE_MATCHING_OBJECT( stats, mvo()
("supply", "0.000 TKN")
("max_supply", "1000.000 TKN")
("issuer", "alice")
);
alice_balance = get_account(N(alice), "3,TKN");
REQUIRE_MATCHING_OBJECT( alice_balance, mvo()
("balance", "0.000 TKN")
);

//trying to retire tokens with zero supply
BOOST_REQUIRE_EQUAL( wasm_assert_msg("overdrawn balance"), retire( N(alice), asset::from_string("1.000 TKN"), "hola" ) );

} FC_LOG_AND_RETHROW()

BOOST_FIXTURE_TEST_CASE( transfer_tests, eosio_token_tester ) try {

auto token = create( N(alice), asset::from_string("1000 CERO"));
Expand Down

0 comments on commit e96f801

Please sign in to comment.