Skip to content
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

eosio.erc2o contract implementation #5

Merged
merged 14 commits into from
Sep 5, 2023
102 changes: 92 additions & 10 deletions antelope_contracts/contracts/erc20/include/erc20/erc20.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,30 +11,112 @@ using namespace intx;

namespace erc20 {

checksum256 make_key(const uint8_t* ptr, size_t len) {
uint8_t buffer[32]={};
check(len <= sizeof(buffer), "len provided to make_key is too small");
memcpy(buffer, ptr, len);
return checksum256(buffer);
}

checksum256 make_key(bytes data){
return make_key((const uint8_t*)data.data(), data.size());
}

class [[eosio::contract]] erc20 : public contract {
public:
using contract::contract;

struct bridge_message_v0 {
eosio::name receiver;
bytes sender;
eosio::time_point timestamp;
bytes value;
bytes data;

EOSLIB_SERIALIZE(bridge_message_v0, (receiver)(sender)(timestamp)(value)(data));
};

using bridge_message_t = std::variant<bridge_message_v0>;

[[eosio::on_notify("*::transfer")]] void transfer(eosio::name from, eosio::name to, eosio::asset quantity, std::string memo);

// evm runtime will call this to notify erc20 about the message from 'from' with 'data'.
[[eosio::action]] void onbridgemsg(name receiver, const bytes& sender, const time_point& timestamp, const bytes& value, const bytes& data);
[[eosio::action]] void init();
[[eosio::action]] void onbridgemsg(const bridge_message_t &message);
[[eosio::action]] void upgrade();

[[eosio::action]] void regtoken(eosio::name eos_contract_name,
std::string evm_token_name, std::string evm_token_symbol, const eosio::asset& ingress_fee, const eosio::asset &egress_fee, uint8_t erc20_precision);

[[eosio::action]] void addegress(const std::vector<name>& accounts);
[[eosio::action]] void removeegress(const std::vector<name>& accounts);

uint64_t get_next_nonce();

struct nextnonce {
name owner;
uint64_t next_nonce = 0;

struct [[eosio::table]] config
{
bytes erc20_addr;
uint64_t primary_key() const { return owner.value; }
EOSLIB_SERIALIZE(nextnonce, (owner)(next_nonce));
};

struct [[eosio::table("implcontract")]] impl_contract_t {
uint64_t id = 0;
bytes address;

uint64_t primary_key() const {
return id;
}
EOSLIB_SERIALIZE(impl_contract_t, (id)(address));
};
typedef eosio::multi_index<"implcontract"_n, impl_contract_t> impl_contract_table_t;

struct [[eosio::table("tokens")]] token_t {
uint64_t id = 0;
eosio::name token_contract;
bytes address; // <-- proxy contract addr
eosio::asset ingress_fee;
eosio::asset balance; // <-- total amount in EVM side
eosio::asset fee_balance;
int8_t erc20_precision = 0;

EOSLIB_SERIALIZE(config, (erc20_addr));
uint64_t primary_key() const {
return id;
}
uint128_t by_contract_symbol() const {
uint128_t v = token_contract.value;
v <<= 64;
v |= ingress_fee.symbol.code().raw();
return v;
}
checksum256 by_address()const {
return make_key(address);
}

EOSLIB_SERIALIZE(token_t, (id)(token_contract)(address)(ingress_fee)(balance)(fee_balance)(erc20_precision));
};
typedef eosio::multi_index<"tokens"_n, token_t,
indexed_by<"by.symbol"_n, const_mem_fun<token_t, uint128_t, &token_t::by_contract_symbol> >,
indexed_by<"by.address"_n, const_mem_fun<token_t, checksum256, &token_t::by_address> >
> token_table_t;

struct [[eosio::table("egresslist")]] allowed_egress_account {
eosio::name account;

private:
uint64_t primary_key() const { return account.value; }
EOSLIB_SERIALIZE(allowed_egress_account, (account));
};
typedef eosio::multi_index<"egresslist"_n, allowed_egress_account> egresslist_table_t;

eosio::singleton<"config"_n, config> _config{get_self(), get_self().value};
void handle_evm_transfer(eosio::asset quantity, const std::string &memo);
void handle_erc20_transfer(const token_t &token, eosio::asset quantity, const std::string &memo);

void call(eosio::name from, const bytes &to, uint128_t value, const bytes &data, uint64_t gas_limit);
// actions defined in evm_runtime contract
void call(eosio::name from, const bytes &to, const bytes& value, const bytes &data, uint64_t gas_limit);
using call_action = action_wrapper<"call"_n, &erc20::call>;

void assertnonce(eosio::name account, uint64_t next_nonce);
using assertnonce_action = action_wrapper<"assertnonce"_n, &erc20::assertnonce>;

};

} // namespace erc20
14 changes: 8 additions & 6 deletions antelope_contracts/contracts/erc20/include/erc20/types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@ typedef std::vector<char> bytes;

constexpr size_t kAddressLength{20};
constexpr size_t kHashLength{32};
constexpr unsigned evm_precision = 6;
constexpr uint64_t evm_gaslimit = 500000;
constexpr uint64_t evm_init_gaslimit = 5000000;
constexpr eosio::name token_account(eosio::name("tethertether"));
constexpr eosio::symbol token_symbol("USDT", 4u);
constexpr uint64_t evm_init_gaslimit = 10000000;

constexpr eosio::name evm_account(eosio::name("eosio.evm"));
constexpr intx::uint256 minimum_natively_representable = intx::exp(10_u256, intx::uint256(evm_precision - token_symbol.precision()));
static_assert(evm_precision - token_symbol.precision() <= 14, "dust math may overflow a uint64_t");
constexpr eosio::name erc2o_account(eosio::name("eosio.erc2o"));

constexpr unsigned evm_precision = 18; // precision of native token(aka.EOS) in EVM side
constexpr eosio::symbol native_token_symbol("EOS", 4u);
constexpr intx::uint256 minimum_natively_representable = intx::exp(10_u256, intx::uint256(evm_precision - native_token_symbol.precision()));


} // namespace erc20
Loading
Loading