Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/connector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub(crate) const PAUSE_WITHDRAW: PausedMask = 1 << 1;
#[derive(BorshSerialize, BorshDeserialize)]
pub struct EthConnectorContract {
contract: EthConnector,
ft: FungibleToken,
pub ft: FungibleToken,
Comment thread
joshuajbouw marked this conversation as resolved.
paused_mask: PausedMask,
}

Expand Down Expand Up @@ -578,7 +578,7 @@ impl EthConnectorContract {
}

/// Save eth-connector contract data
fn save_ft_contract(&mut self) {
pub(crate) fn save_ft_contract(&mut self) {
sdk::save_contract(
&Self::get_contract_key(&EthConnectorStorageId::FungibleToken),
&self.ft,
Expand Down
37 changes: 37 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,43 @@ mod contract {
);
}

/// Due to the design change to stop minting and burning bridged ETH tokens
/// (see https://github.com/aurora-is-near/aurora-engine/pull/133 ),
/// there is currently an incorrect number of tokens in the Aurora NEP-141 token
/// account. This issue only impacts testnet because at the time the design was changed
/// the eth-connector had not been deployed to mainnet. The purpose of this function is
/// to mint the correct number of tokens in order to make up for the ones that were burned
/// before the design change in #133.
#[cfg(feature = "testnet")]
#[no_mangle]
pub extern "C" fn balance_evm_and_nep_141() {
use crate::precompiles::native::{ExitToEthereum, ExitToNear};
use crate::prelude::String;

let mut connector = EthConnectorContract::get_instance();
let aurora_account = unsafe { String::from_utf8_unchecked(sdk::current_account_id()) };
Comment thread
joshuajbouw marked this conversation as resolved.
let aurora_nep_141_balance = connector.ft.ft_balance_of(&aurora_account);
let total_evm_balance = connector.ft.ft_total_eth_supply_on_aurora();
let exit_to_near_balance = Engine::get_balance(&ExitToNear::ADDRESS).raw().low_u128();
let exit_to_eth_balance = Engine::get_balance(&ExitToEthereum::ADDRESS)
.raw()
.low_u128();

// ETH sent to the exit precompiles is no longer accessible (and would have already been
// transferred from the Aurora account in the NEP-141 contract).
let available_evm_balance = total_evm_balance - exit_to_eth_balance - exit_to_near_balance;

// After #133 it should be true that `aurora_nep_141_balance == available_evm_balance`.
// If it is not then we mint tokens to make this the case.
if aurora_nep_141_balance < available_evm_balance {
let missing_balance = available_evm_balance - aurora_nep_141_balance;
connector
.ft
.internal_deposit_eth_to_near(&aurora_account, missing_balance);
connector.save_ft_contract();
}
}

#[cfg(feature = "integration-test")]
#[no_mangle]
pub extern "C" fn verify_log_entry() {
Expand Down
2 changes: 1 addition & 1 deletion src/precompiles/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ mod hash;
mod identity;
mod modexp;
#[cfg_attr(not(feature = "contract"), allow(dead_code))]
mod native;
pub(crate) mod native;
mod secp256k1;

#[derive(Debug)]
Expand Down
4 changes: 2 additions & 2 deletions src/precompiles/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ impl ExitToNear {
///
/// Address: `0xe9217bc70b7ed1f598ddd3199e80b093fa71124f`
/// This address is computed as: `&keccak("exitToNear")[12..]`
pub(super) const ADDRESS: Address =
pub(crate) const ADDRESS: Address =
super::make_address(0xe9217bc7, 0x0b7ed1f598ddd3199e80b093fa71124f);
Comment thread
joshuajbouw marked this conversation as resolved.
}

Expand Down Expand Up @@ -188,7 +188,7 @@ impl ExitToEthereum {
///
/// Address: `0xb0bd02f6a392af548bdf1cfaee5dfa0eefcc8eab`
/// This address is computed as: `&keccak("exitToEthereum")[12..]`
pub(super) const ADDRESS: Address =
pub(crate) const ADDRESS: Address =
super::make_address(0xb0bd02f6, 0xa392af548bdf1cfaee5dfa0eefcc8eab);
Comment thread
joshuajbouw marked this conversation as resolved.
}

Expand Down
63 changes: 63 additions & 0 deletions src/tests/sanity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,69 @@ fn test_block_hash_contract() {
test_utils::panic_on_fail(result.status);
}

#[cfg(feature = "testnet-test")]
#[test]
fn test_balance_evm_and_nep_141() {
use crate::precompiles::native::{ExitToEthereum, ExitToNear};

let (mut runner, _, _) = initialize_transfer();
let caller = runner.aurora_account_id.clone();

// Include some ETH at the exit precompiles addresses for testing purposes
runner.create_address(ExitToNear::ADDRESS, TRANSFER_AMOUNT, U256::zero());
runner.create_address(
ExitToEthereum::ADDRESS,
TRANSFER_AMOUNT + TRANSFER_AMOUNT,
U256::zero(),
);

let aurora_balance = |runner: &mut test_utils::AuroraRunner| -> u128 {
let (maybe_result, maybe_err) = runner.call(
"ft_balance_of",
caller.clone(),
format!(r#"{{"account_id": "{}"}}"#, runner.aurora_account_id).into_bytes(),
);
assert!(maybe_err.is_none());
let result = maybe_result.unwrap();
String::from_utf8(result.return_data.as_value().unwrap())
.unwrap()
.parse()
.unwrap()
};

let evm_balance = |runner: &mut test_utils::AuroraRunner| -> u128 {
let exit_to_near_balance = runner.get_balance(ExitToNear::ADDRESS).raw().low_u128();
let exit_to_eth_balance = runner.get_balance(ExitToEthereum::ADDRESS).raw().low_u128();
let total_evm_balance: u128 = {
let (maybe_result, maybe_err) =
runner.call("ft_total_eth_supply_on_aurora", caller.clone(), Vec::new());
assert!(maybe_err.is_none());
let result = maybe_result.unwrap();
String::from_utf8(result.return_data.as_value().unwrap())
.unwrap()
.parse()
.unwrap()
};
total_evm_balance - exit_to_near_balance - exit_to_eth_balance
};

// There is not enough in the Aurora NEP-141 account, relative to how much is in the EVM;
assert_eq!(evm_balance(&mut runner), INITIAL_BALANCE.raw().low_u128());
assert_eq!(aurora_balance(&mut runner), 0);

// Call method to restore balance
let (_, maybe_err) = runner.call("balance_evm_and_nep_141", caller.clone(), Vec::new());
assert!(maybe_err.is_none());

// Balance is restored
assert_eq!(aurora_balance(&mut runner), evm_balance(&mut runner));

// Calling multiple times is a no-op
let (_, maybe_err) = runner.call("balance_evm_and_nep_141", caller.clone(), Vec::new());
assert!(maybe_err.is_none());
assert_eq!(aurora_balance(&mut runner), evm_balance(&mut runner));
}

// Same as `test_eth_transfer_insufficient_balance` above, except runs through
// `near-sdk-sim` instead of `near-vm-runner`. This is important because `near-sdk-sim`
// has more production logic, in particular, state revert on contract panic.
Expand Down