Skip to content

Commit

Permalink
Merge pull request #47 from eosnetworkfoundation/yarkin/exsat_fixes
Browse files Browse the repository at this point in the history
Full support for upgrade
  • Loading branch information
yarkinwho authored Aug 8, 2024
2 parents 65a3373 + 9778a59 commit 7a440c5
Showing 3 changed files with 131 additions and 2 deletions.
2 changes: 2 additions & 0 deletions antelope_contracts/contracts/erc20/include/erc20/erc20.hpp
Original file line number Diff line number Diff line change
@@ -60,6 +60,7 @@ class [[eosio::contract]] erc20 : public contract {
[[eosio::action]] void init(eosio::name evm_account, eosio::symbol gas_token_symbol, uint64_t gaslimit, uint64_t init_gaslimit);

[[eosio::action]] void setgaslimit(std::optional<uint64_t> gaslimit, std::optional<uint64_t> init_gaslimit);
[[eosio::action]] void callupgrade(eosio::name token_contract, eosio::symbol token_symbol);

struct [[eosio::table("implcontract")]] impl_contract_t {
uint64_t id = 0;
@@ -136,6 +137,7 @@ class [[eosio::contract]] erc20 : public contract {

uint64_t get_next_nonce();
void handle_erc20_transfer(const token_t &token, eosio::asset quantity, const std::string &memo);
void handle_call_upgrade(const bytes& proxy_address);

private:
eosio::name receiver_account()const;
47 changes: 45 additions & 2 deletions antelope_contracts/contracts/erc20/src/erc20.cpp
Original file line number Diff line number Diff line change
@@ -84,7 +84,7 @@ void erc20::upgrade() {
evmc::address impl_addr = silkworm::create_address(reserved_addr, next_nonce);

contract_table.emplace(_self, [&](auto &v) {
v.id = id;
v.id = contract_table.available_primary_key();
v.address.resize(kAddressLength);
memcpy(&(v.address[0]), impl_addr.bytes, kAddressLength);
});
@@ -100,7 +100,7 @@ void erc20::upgradeto(std::string impl_address) {
impl_contract_table_t contract_table(_self, _self.value);

contract_table.emplace(_self, [&](auto &v) {
v.id = id;
v.id = contract_table.available_primary_key();
v.address.resize(kAddressLength);
memcpy(&(v.address[0]), address_bytes->data(), kAddressLength);
});
@@ -477,4 +477,47 @@ inline eosio::name erc20::receiver_account()const {
return get_self();
}

void erc20::callupgrade(eosio::name token_contract, eosio::symbol token_symbol){
require_auth(get_self());

token_table_t token_table(_self, _self.value);
auto index_symbol = token_table.get_index<"by.symbol"_n>();
auto token_table_iter = index_symbol.find(token_symbol_key(token_contract, token_symbol.code()));
eosio::check(token_table_iter != index_symbol.end(), "token not registered");

handle_call_upgrade(token_table_iter->address);
}

void erc20::handle_call_upgrade(const bytes& proxy_address) {
config_t config = get_config();
impl_contract_table_t contract_table(_self, _self.value);
eosio::check(contract_table.begin() != contract_table.end(), "no implementaion contract available");
auto contract_itr = contract_table.end();
--contract_itr;

auto pack_uint32 = [&](bytes &ds, uint32_t val) {
uint8_t val_[32] = {};
val_[28] = (uint8_t)(val >> 24);
val_[29] = (uint8_t)(val >> 16);
val_[30] = (uint8_t)(val >> 8);
val_[31] = (uint8_t)val;
ds.insert(ds.end(), val_, val_ + sizeof(val_));
};

bytes call_data;
// sha(upgradeTo(address)) == 3659cfe6
uint8_t func_[4] = {0x36,0x59,0xcf,0xe6};
call_data.insert(call_data.end(), func_, func_ + sizeof(func_));


call_data.insert(call_data.end(), 32 - kAddressLength, 0); // padding for address offset 0
call_data.insert(call_data.end(), contract_itr->address.begin(), contract_itr->address.end());

bytes value_zero;
value_zero.resize(32, 0);

evm_runtime::call_action call_act(config.evm_account, {{receiver_account(), "active"_n}});
call_act.send(receiver_account(), proxy_address, value_zero, call_data, config.evm_gaslimit);
}

} // namespace erc20
84 changes: 84 additions & 0 deletions antelope_contracts/tests/erc20/integrated_tests.cpp
Original file line number Diff line number Diff line change
@@ -14,6 +14,7 @@
#include <vector>

#include "erc20_tester.hpp"
#include <erc20/bytecode.hpp>

using namespace eosio;
using namespace eosio::chain;
@@ -273,6 +274,89 @@ try {
}
FC_LOG_AND_RETHROW()

BOOST_FIXTURE_TEST_CASE(it_upgrade, it_tester)
try {



evm_eoa evm1;
auto addr_alice = silkworm::make_reserved_address("alice"_n.to_uint64_t());

// Give evm1 some EOS
transfer_token(eos_token_account, "alice"_n, evm_account, make_asset(1000000, eos_token_symbol), evm1.address_0x().c_str());
produce_block();


// USDT balance should be zero
auto bal = balanceOf(evm1.address_0x().c_str());
BOOST_REQUIRE(bal == 0);

produce_block();

transfer_token(token_account, "alice"_n, erc20_account, make_asset(10000, token_symbol), evm1.address_0x().c_str());

bal = balanceOf(evm1.address_0x().c_str());
BOOST_REQUIRE(bal == 990000);
BOOST_REQUIRE(99990000 == get_balance("alice"_n, token_account, symbol::from_string("4,USDT")).get_amount());
auto tokenInfo = getRegistedTokenInfo();
BOOST_REQUIRE(tokenInfo.balance == make_asset(9900, token_symbol));
BOOST_REQUIRE(tokenInfo.fee_balance == make_asset(100, token_symbol));

produce_block();

auto fee = egressFee();
// received = 1000/1e6*1e4 = 10
bridgeTransferERC20(evm1, addr_alice, 1000, "aaa", fee);
produce_block();

bal = balanceOf(evm1.address_0x().c_str());

BOOST_REQUIRE(bal == 989000);
bal = get_balance("alice"_n, token_account, symbol::from_string("4,USDT")).get_amount();

BOOST_REQUIRE(99990010 == get_balance("alice"_n, token_account, symbol::from_string("4,USDT")).get_amount());

// upgrade

evm_eoa deployer;
evmc::address impl_addr = silkworm::create_address(deployer.address, deployer.next_nonce);

transfer_token(eos_token_account, faucet_account_name, evmin_account, make_asset(1000000, eos_token_symbol), deployer.address_0x().c_str());

auto txn = prepare_deploy_contract_tx(solidity::erc20::bytecode, sizeof(solidity::erc20::bytecode), 10'000'000);

deployer.sign(txn);
pushtx(txn);
produce_block();

push_action(erc20_account, "upgradeto"_n, erc20_account, mvo()("impl_address",fc::variant(impl_addr).as_string()));

produce_block();

push_action(erc20_account, "callupgrade"_n, erc20_account, mvo()("token_contract",token_account)("token_symbol",symbol::from_string("4,USDT")));

produce_block();

// Perform some basic tests again

transfer_token(token_account, "alice"_n, erc20_account, make_asset(10000, token_symbol), evm1.address_0x().c_str());

bal = balanceOf(evm1.address_0x().c_str());

BOOST_REQUIRE(bal == 989000 + 990000);

fee = egressFee();
// received = 1000/1e6*1e4 = 10
bridgeTransferERC20(evm1, addr_alice, 1000, "aaa", fee);
produce_block();

bal = balanceOf(evm1.address_0x().c_str());

BOOST_REQUIRE(bal == 989000 * 2);

}
FC_LOG_AND_RETHROW()

BOOST_FIXTURE_TEST_CASE(it_unregtoken, it_tester)
try {
evm_eoa evm1;

0 comments on commit 7a440c5

Please sign in to comment.