-
Notifications
You must be signed in to change notification settings - Fork 80
/
one_inch.rs
146 lines (127 loc) · 5.57 KB
/
one_inch.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
use crate::prelude::parameters::SubmitResult;
use crate::prelude::{Wei, U256};
use crate::utils::one_inch::liquidity_protocol;
use crate::utils::{self, assert_gas_bound};
use aurora_engine_types::{borsh::BorshDeserialize, types::Address};
use libsecp256k1::SecretKey;
use near_vm_runner::logic::VMOutcome;
use std::sync::Once;
const INITIAL_BALANCE: Wei = Wei::new_u64(1_000_000);
const INITIAL_NONCE: u64 = 0;
static DOWNLOAD_COMPILE_ONCE: Once = Once::new();
#[test]
fn test_1inch_liquidity_protocol() {
let (mut runner, mut source_account) = initialize();
let mut helper = liquidity_protocol::Helper {
runner: &mut runner,
signer: &mut source_account,
};
let (result, profile, deployer_address) = helper.create_mooniswap_deployer();
assert!(result.gas_used >= 5_100_000); // more than 5.1M EVM gas used
assert_gas_bound(profile.all_gas(), 11); // less than 11 NEAR Tgas used
let (result, profile, pool_factory) = helper.create_pool_factory(&deployer_address);
assert!(result.gas_used >= 2_800_000); // more than 2.8M EVM gas used
assert_gas_bound(profile.all_gas(), 11); // less than 11 NEAR Tgas used
// create some ERC-20 tokens to have a liquidity pool for
let signer_address = utils::address_from_secret_key(&helper.signer.secret_key);
let token_a = helper.create_erc20("TokenA", "AAA");
let token_b = helper.create_erc20("TokenB", "BBB");
helper.mint_erc20_tokens(&token_a, signer_address);
helper.mint_erc20_tokens(&token_b, signer_address);
let (result, profile, pool) =
helper.create_pool(&pool_factory, token_a.0.address, token_b.0.address);
assert!(result.gas_used >= 4_500_000); // more than 4.5M EVM gas used
assert_gas_bound(profile.all_gas(), 21);
// Approve giving ERC-20 tokens to the pool
helper.approve_erc20_tokens(&token_a, pool.address());
helper.approve_erc20_tokens(&token_b, pool.address());
// I don't understand why this is needed but for some reason the 1inch
// contract divides by zero unless I mess with the time.
helper.runner.context.block_timestamp += 10_000_000 * 1_000_000_000;
let (result, profile) = helper.pool_deposit(
&pool,
&liquidity_protocol::DepositArgs {
min_token_a: U256::zero(),
min_token_b: U256::zero(),
max_token_a: 10_000.into(),
max_token_b: 10_000.into(),
},
);
assert!(result.gas_used >= 302_000); // more than 302k EVM gas used
assert_gas_bound(profile.all_gas(), 23);
// Same here
helper.runner.context.block_timestamp += 10_000_000 * 1_000_000_000;
let (result, profile) = helper.pool_swap(
&pool,
&liquidity_protocol::SwapArgs {
src_token: token_a.0.address,
dst_token: token_b.0.address,
amount: 1000.into(),
min_amount: U256::one(),
referral: signer_address,
},
);
assert!(result.gas_used >= 210_000); // more than 210k EVM gas used
assert_gas_bound(profile.all_gas(), 25);
let (result, profile) = helper.pool_withdraw(
&pool,
&liquidity_protocol::WithdrawArgs {
amount: 100.into(),
min_token_a: U256::one(),
min_token_b: U256::one(),
},
);
assert!(result.gas_used >= 150_000); // more than 150k EVM gas used
assert_gas_bound(profile.all_gas(), 21);
}
#[test]
fn test_1_inch_limit_order_deploy() {
// set up Aurora runner and accounts
let (mut runner, mut source_account) = initialize();
let outcome = deploy_1_inch_limit_order_contract(&mut runner, &mut source_account);
let profile = utils::ExecutionProfile::new(&outcome);
let result: SubmitResult =
SubmitResult::try_from_slice(&outcome.return_data.as_value().unwrap()).unwrap();
assert!(result.status.is_ok());
// more than 3.5 million Ethereum gas used
assert!(result.gas_used > 3_500_000);
// less than 12 NEAR TGas used
assert_gas_bound(profile.all_gas(), 12);
// at least 45% of which is from wasm execution
let wasm_fraction = 100 * profile.wasm_gas() / profile.all_gas();
assert!(
(40..=50).contains(&wasm_fraction),
"{wasm_fraction}% is not between 45% and 55%",
);
}
fn deploy_1_inch_limit_order_contract(
runner: &mut utils::AuroraRunner,
signer: &mut utils::Signer,
) -> VMOutcome {
let artifacts_path = utils::one_inch::download_and_compile_solidity_sources(
"limit-order-protocol",
&DOWNLOAD_COMPILE_ONCE,
);
let contract_path = artifacts_path.join("LimitOrderProtocol.sol/LimitOrderProtocol.json");
let constructor =
utils::solidity::ContractConstructor::compile_from_extended_json(contract_path);
let weth = Address::from_array([0; 20]);
let nonce = signer.use_nonce();
let deploy_tx =
constructor.deploy_with_args(nonce.into(), &[ethabi::Token::Address(weth.raw())]);
let tx = utils::sign_transaction(deploy_tx, Some(runner.chain_id), &signer.secret_key);
let outcome = runner.call(utils::SUBMIT, "any_account.near", rlp::encode(&tx).to_vec());
assert!(outcome.is_ok());
outcome.unwrap()
}
fn initialize() -> (utils::AuroraRunner, utils::Signer) {
// set up Aurora runner and accounts
let mut runner = utils::deploy_runner();
let mut rng = rand::thread_rng();
let source_account = SecretKey::random(&mut rng);
let source_address = utils::address_from_secret_key(&source_account);
runner.create_address(source_address, INITIAL_BALANCE, INITIAL_NONCE.into());
let mut signer = utils::Signer::new(source_account);
signer.nonce = INITIAL_NONCE;
(runner, signer)
}