未验证 提交 75eb015f 编写于 作者: D Daniel Larimer 提交者: GitHub

Merge pull request #2735 from EOSIO/decimals

Fix for #2322 - eosio.token transfer succeeds or fails depending on decimal digits count
......@@ -78,6 +78,9 @@ void token::transfer( account_name from,
eosio_assert( quantity.is_valid(), "invalid quantity" );
eosio_assert( quantity.amount > 0, "must transfer positive quantity" );
if ( quantity.symbol.precision() != st.supply.symbol.precision() )
quantity.adjust_precision( st.supply.symbol );
sub_balance( from, quantity, st );
add_balance( to, quantity, st, from );
}
......
......@@ -251,6 +251,18 @@ namespace eosio {
symbol.print(false);
}
void adjust_precision(const symbol_type& ref_sym) {
eosio_assert(this->symbol.name() == ref_sym.name(), "comparison of symbols with different names is not allowed");
if (this->symbol.precision() == ref_sym.precision())
return;
eosio_assert(ref_sym.precision() >= this->symbol.precision(), "asset symbol has higher precision than expected");
for (uint8_t i = 0; i < ref_sym.precision() - this->symbol.precision(); ++i) {
printi(amount);
this->amount *= 10;
}
this->symbol.value = ref_sym.value;
}
EOSLIB_SERIALIZE( asset, (amount)(symbol) )
};
......
......@@ -52,7 +52,17 @@ class currency_tester : public TESTER {
return get_currency_balance(N(eosio.token), symbol(SY(4,CUR)), account);
}
auto transfer(const account_name& from, const account_name& to, const std::string& quantity, const std::string& memo = "") {
auto trace = push_action(from, N(transfer), mutable_variant_object()
("from", from)
("to", to)
("quantity", quantity)
("memo", memo)
);
produce_block();
return trace;
}
currency_tester()
:TESTER(),abi_ser(json::from_string(eosio_token_abi).as<abi_def>())
{
......@@ -523,4 +533,52 @@ BOOST_FIXTURE_TEST_CASE( test_deferred_failure, currency_tester ) try {
} FC_LOG_AND_RETHROW() /// test_currency
BOOST_FIXTURE_TEST_CASE( test_input_quantity, currency_tester ) try {
produce_blocks(2);
create_accounts( {N(alice), N(bob), N(carl)} );
// transfer to alice using right precision
{
auto trace = transfer(eosio_token, N(alice), "100.0000 CUR");
BOOST_CHECK_EQUAL(true, chain_has_transaction(trace->id));
BOOST_CHECK_EQUAL(asset::from_string( "100.0000 CUR"), get_balance(N(alice)));
BOOST_CHECK_EQUAL(1000000, get_balance(N(alice)).amount);
}
// transfer from alice to bob using no decimal point
{
auto trace = transfer(N(alice), N(bob), "13 CUR");
BOOST_CHECK_EQUAL(true, chain_has_transaction(trace->id));
BOOST_CHECK_EQUAL(asset::from_string("13.0000 CUR"), get_balance(N(bob)));
BOOST_CHECK_EQUAL(asset::from_string("87.0000 CUR"), get_balance(N(alice)));
}
// transfer from bob to carl using lower precision
{
auto trace = transfer(N(bob), N(carl), "2.01 CUR");
BOOST_CHECK_EQUAL(true, chain_has_transaction(trace->id));
BOOST_CHECK_EQUAL(asset::from_string("2.0100 CUR"), get_balance(N(carl)));
BOOST_CHECK_EQUAL(asset::from_string("10.9900 CUR"), get_balance(N(bob)));
}
// transfer using higher precision fails
{
BOOST_REQUIRE_EXCEPTION(transfer(N(alice), N(carl), "5.34567 CUR"), assert_exception,
[](const assert_exception& e) -> bool {
return e.get_log().at(0).get_message() == "condition: assertion failed: asset symbol has higher precision than expected";
});
}
// transfer using different symbol name fails
{
BOOST_REQUIRE_THROW(transfer(N(alice), N(carl), "20.50 USD"), assert_exception);
}
} FC_LOG_AND_RETHROW() /// test_currency
BOOST_AUTO_TEST_SUITE_END()
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册