near/audit2: more audit cleanup
This commit is contained in:
parent
dc28f88218
commit
0fc3e8badc
|
@ -0,0 +1,14 @@
|
||||||
|
FROM debian@sha256:2ce44bbc00a79113c296d9d25524e15d423b23303fdbbe20190d2f96e0aeb251 as near-contracts-build
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get install apt-utils && apt-get install -y python3 npm curl --no-install-recommends
|
||||||
|
RUN apt-get install -y build-essential git
|
||||||
|
|
||||||
|
ADD . .
|
||||||
|
RUN ./setup-rust.sh
|
||||||
|
RUN ./build-contracts.sh
|
||||||
|
|
||||||
|
FROM scratch AS near-contracts-export
|
||||||
|
|
||||||
|
COPY --from=near-contracts-build /contracts/token-bridge/target/wasm32-unknown-unknown/release/near_token_bridge.wasm near_token_bridge.wasm
|
||||||
|
COPY --from=near-contracts-build /contracts/wormhole/target/wasm32-unknown-unknown/release/near_wormhole.wasm near_wormhole.wasm
|
||||||
|
|
|
@ -4,6 +4,14 @@ test: build node_modules
|
||||||
|
|
||||||
all: node_modules build nearcore
|
all: node_modules build nearcore
|
||||||
|
|
||||||
|
.PHONY: artifacts
|
||||||
|
artifacts:
|
||||||
|
mkdir -p $@
|
||||||
|
@echo "Building artifacts for near"
|
||||||
|
DOCKER_BUILDKIT=1 docker build -f Dockerfile.build -t near-builder -o type=local,dest=$@ .
|
||||||
|
cd $@ && ls | xargs sha256sum > checksums.txt
|
||||||
|
|
||||||
|
|
||||||
build: contracts/ft/target/wasm32-unknown-unknown/release/near_ft.wasm \
|
build: contracts/ft/target/wasm32-unknown-unknown/release/near_ft.wasm \
|
||||||
contracts/mock-bridge-integration/target/wasm32-unknown-unknown/release/near_mock_bridge_integration.wasm \
|
contracts/mock-bridge-integration/target/wasm32-unknown-unknown/release/near_mock_bridge_integration.wasm \
|
||||||
contracts/mock-bridge-token/target/wasm32-unknown-unknown/release/near_mock_bridge_token.wasm \
|
contracts/mock-bridge-token/target/wasm32-unknown-unknown/release/near_mock_bridge_token.wasm \
|
||||||
|
|
155
near/NOTES.md
155
near/NOTES.md
|
@ -1,155 +0,0 @@
|
||||||
01000000000100bc708675768ba853af2e01c6217317fbb68500a508a39fece15dac27d36c7c804cf94ad9e4b2134209bbdad7c9479d9929c60bda4612a74c61c06efebacc4da401000003cb5d690100000200000000000000000000000026b4afb60d6c903165150c6f0aa14f8016be4aec00000000000000010f01000000000000000000000000d1a269d9b0dfb66cfdaf89cf0c6e6f8df0615ad00002415045f09f9092000000000000000000000000000000000000000000000000004e6f7420616e2041504520f09f90920000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a5268747470733a2f2f636c6f7564666c6172652d697066732e636f6d2f697066732f516d65536a53696e4870506e6d586d73704d6a776958794e367a533445397a63636172694752336a7863615774712f31301212121212121212121212121212121212121212121212121212121212121212000f
|
|
||||||
|
|
||||||
--
|
|
||||||
|
|
||||||
1) vaa is received for a user for a token where the user has not paid the storage deposit in that token
|
|
||||||
2) vaa gets submitted without using the SDK which detects this and correctly registers/pays-storage-deposit
|
|
||||||
|
|
||||||
choice 1:
|
|
||||||
|
|
||||||
VAA gets consumed but the tokens don't get transfered
|
|
||||||
|
|
||||||
choice 2:
|
|
||||||
|
|
||||||
The token bridge proactively throws money at the token, which it hopes will get refunded,
|
|
||||||
to pay for storage if it is not already there
|
|
||||||
|
|
||||||
VAA gets consumed but the money might not get refunded... due to token implementor being an asshat
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// demonstrates how to query the state without setting
|
|
||||||
// up an account. (View methods only)
|
|
||||||
const { providers } = require("near-api-js");
|
|
||||||
//network config (replace testnet with mainnet or betanet)
|
|
||||||
const provider = new providers.JsonRpcProvider("https://rpc.testnet.near.org");
|
|
||||||
|
|
||||||
getState();
|
|
||||||
|
|
||||||
async function getState() {
|
|
||||||
const rawResult = await provider.query({
|
|
||||||
request_type: "call_function",
|
|
||||||
account_id: "guest-book.testnet",
|
|
||||||
method_name: "getMessages",
|
|
||||||
args_base64: "e30=",
|
|
||||||
finality: "optimistic",
|
|
||||||
});
|
|
||||||
|
|
||||||
// format result
|
|
||||||
const res = JSON.parse(Buffer.from(rawResult.result).toString());
|
|
||||||
console.log(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
import { Account as nearAccount } from "near-api-js";
|
|
||||||
|
|
||||||
My impression is:
|
|
||||||
|
|
||||||
https://docs.near.org/docs/tutorials/near-indexer
|
|
||||||
|
|
||||||
https://thewiki.near.page/events-api
|
|
||||||
|
|
||||||
==
|
|
||||||
kubectl exec -it near-0 -c near-node -- /bin/bash
|
|
||||||
|
|
||||||
My NEAR notes so far...
|
|
||||||
|
|
||||||
If needed, install `Rust`:
|
|
||||||
|
|
||||||
curl https://sh.rustup.rs -sSf | sh
|
|
||||||
|
|
||||||
You need at least version 1.56 or later
|
|
||||||
|
|
||||||
rustup default 1.56
|
|
||||||
rustup update
|
|
||||||
rustup target add wasm32-unknown-unknown
|
|
||||||
|
|
||||||
If needed, install `near-cli`:
|
|
||||||
|
|
||||||
npm install near-cli -g
|
|
||||||
|
|
||||||
To install the npm dependencies of this test program
|
|
||||||
|
|
||||||
npm install
|
|
||||||
|
|
||||||
for the near sdk, we are dependent on 4.0.0 or later (where the ecrecover API is)
|
|
||||||
|
|
||||||
https://docs.rs/near-sdk/4.0.0/near_sdk/index.html
|
|
||||||
near-sdk = { version = "4.0.0", features = ["unstable"] }
|
|
||||||
|
|
||||||
This has been stuck into Cargo.toml
|
|
||||||
|
|
||||||
to bring up the sandbox, start a tmux window and run
|
|
||||||
|
|
||||||
rm -rf _sandbox
|
|
||||||
mkdir -p _sandbox
|
|
||||||
near-sandbox --home _sandbox init
|
|
||||||
near-sandbox --home _sandbox run
|
|
||||||
|
|
||||||
https://docs.near.org/docs/develop/contracts/sandbox
|
|
||||||
|
|
||||||
First thing, lets put this in a docker in Tilt..
|
|
||||||
|
|
||||||
vaa_verify?
|
|
||||||
|
|
||||||
near-sdk-rs/near-sdk/src/environment/env.rs: (still unstable)
|
|
||||||
|
|
||||||
/// Recovers an ECDSA signer address from a 32-byte message `hash` and a corresponding `signature`
|
|
||||||
/// along with `v` recovery byte.
|
|
||||||
///
|
|
||||||
/// Takes in an additional flag to check for malleability of the signature
|
|
||||||
/// which is generally only ideal for transactions.
|
|
||||||
///
|
|
||||||
/// Returns 64 bytes representing the public key if the recovery was successful.
|
|
||||||
#[cfg(feature = "unstable")]
|
|
||||||
pub fn ecrecover(
|
|
||||||
hash: &[u8],
|
|
||||||
signature: &[u8],
|
|
||||||
v: u8,
|
|
||||||
malleability_flag: bool,
|
|
||||||
) -> Option<[u8; 64]> {
|
|
||||||
unsafe {
|
|
||||||
let return_code = sys::ecrecover(
|
|
||||||
hash.len() as _,
|
|
||||||
hash.as_ptr() as _,
|
|
||||||
signature.len() as _,
|
|
||||||
signature.as_ptr() as _,
|
|
||||||
v as u64,
|
|
||||||
malleability_flag as u64,
|
|
||||||
ATOMIC_OP_REGISTER,
|
|
||||||
);
|
|
||||||
if return_code == 0 {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(read_register_fixed_64(ATOMIC_OP_REGISTER))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
you can look for test_ecrecover() in the same file...
|
|
||||||
|
|
||||||
When building the sandbox, it is on port 3030 and we will need access to the validator_key.json...
|
|
||||||
|
|
||||||
curl http://localhost:3031/validator_key.json
|
|
||||||
|
|
||||||
function getConfig(env) {
|
|
||||||
switch (env) {
|
|
||||||
case "sandbox":
|
|
||||||
case "local":
|
|
||||||
return {
|
|
||||||
networkId: "sandbox",
|
|
||||||
nodeUrl: "http://localhost:3030",
|
|
||||||
masterAccount: "test.near",
|
|
||||||
contractAccount: "wormhole.test.near",
|
|
||||||
keyPath: "./_sandbox/validator_key.json",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.function_call(
|
|
||||||
b"new".to_vec(),
|
|
||||||
ft,
|
|
||||||
data.to_vec(),
|
|
||||||
vaa.sequence,
|
|
||||||
)
|
|
|
@ -1,8 +1,2 @@
|
||||||
-- bridge for nep141/nep148 tokens --
|
|
||||||
|
|
||||||
https://nomicon.io/Standards/Tokens/FungibleToken/Core#reference-level-explanation
|
|
||||||
|
|
||||||
|
|
||||||
welcome to wormhole on near
|
welcome to wormhole on near
|
||||||
|
|
||||||
all near tokens and $NEAR itself will go to the token account...
|
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
source $HOME/.cargo/env
|
||||||
|
make build
|
||||||
|
|
|
@ -587,7 +587,9 @@ impl TokenBridge {
|
||||||
file!(),
|
file!(),
|
||||||
line!()
|
line!()
|
||||||
));
|
));
|
||||||
ext_ft_contract::ext(asset_token_account.clone()).update_ft(
|
ext_ft_contract::ext(asset_token_account.clone())
|
||||||
|
.with_static_gas(Gas(10_000_000_000_000))
|
||||||
|
.update_ft(
|
||||||
ft,
|
ft,
|
||||||
data.to_vec(),
|
data.to_vec(),
|
||||||
vaa.sequence,
|
vaa.sequence,
|
||||||
|
@ -802,7 +804,7 @@ impl TokenBridge {
|
||||||
Promise::new(refund_to).transfer(env::attached_deposit());
|
Promise::new(refund_to).transfer(env::attached_deposit());
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
let a = AccountId::new_unchecked(account);
|
let a = AccountId::try_from(account).unwrap();
|
||||||
self.hash_map.insert(&account_hash, &a);
|
self.hash_map.insert(&account_hash, &a);
|
||||||
|
|
||||||
if env::storage_usage() < storage_used {
|
if env::storage_usage() < storage_used {
|
||||||
|
@ -1652,32 +1654,30 @@ impl TokenBridge {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[init(ignore_state)]
|
// #[init(ignore_state)]
|
||||||
#[payable]
|
// #[payable]
|
||||||
pub fn migrate() -> Self {
|
// #[private]
|
||||||
if env::attached_deposit() != 1 {
|
// pub fn migrate() -> Self {
|
||||||
env::panic_str("Need money");
|
// if env::attached_deposit() != 1 {
|
||||||
}
|
// env::panic_str("Need money");
|
||||||
let old_state: OldPortal = env::state_read().expect("failed");
|
// }
|
||||||
if env::signer_account_pk() != old_state.owner_pk {
|
// let old_state: OldPortal = env::state_read().expect("failed");
|
||||||
env::panic_str("CannotCallMigrate");
|
// env::log_str(&format!("token-bridge/{}#{}: migrate", file!(), line!(),));
|
||||||
}
|
// Self {
|
||||||
env::log_str(&format!("token-bridge/{}#{}: migrate", file!(), line!(),));
|
// booted: old_state.booted,
|
||||||
Self {
|
// core: old_state.core,
|
||||||
booted: old_state.booted,
|
// gov_idx: 0,
|
||||||
core: old_state.core,
|
// dups: LookupMap::new(b"d".to_vec()),
|
||||||
gov_idx: 0,
|
// owner_pk: old_state.owner_pk,
|
||||||
dups: LookupMap::new(b"d".to_vec()),
|
// emitter_registration: old_state.emitter_registration,
|
||||||
owner_pk: old_state.owner_pk,
|
// last_asset: old_state.last_asset,
|
||||||
emitter_registration: old_state.emitter_registration,
|
// upgrade_hash: old_state.upgrade_hash,
|
||||||
last_asset: old_state.last_asset,
|
// tokens: old_state.tokens,
|
||||||
upgrade_hash: old_state.upgrade_hash,
|
// key_map: old_state.key_map,
|
||||||
tokens: old_state.tokens,
|
// hash_map: old_state.hash_map,
|
||||||
key_map: old_state.key_map,
|
// bank: old_state.bank,
|
||||||
hash_map: old_state.hash_map,
|
// }
|
||||||
bank: old_state.bank,
|
// }
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// let result = await userAccount.functionCall({
|
// let result = await userAccount.functionCall({
|
||||||
|
|
|
@ -601,30 +601,28 @@ impl Wormhole {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
#[init(ignore_state)]
|
// #[init(ignore_state)]
|
||||||
#[payable]
|
// #[payable]
|
||||||
pub fn migrate() -> Self {
|
// #[private]
|
||||||
// call migrate on self
|
// pub fn migrate() -> Self {
|
||||||
if env::attached_deposit() != 1 {
|
// // call migrate on self
|
||||||
env::panic_str("Need money");
|
// if env::attached_deposit() != 1 {
|
||||||
}
|
// env::panic_str("Need money");
|
||||||
let old_state: OldWormhole = env::state_read().expect("failed");
|
// }
|
||||||
if env::signer_account_pk() != old_state.owner_pk {
|
// let old_state: OldWormhole = env::state_read().expect("failed");
|
||||||
env::panic_str("CannotCallMigrate");
|
// env::log_str(&format!("wormhole/{}#{}: migrate", file!(), line!(),));
|
||||||
}
|
// Self {
|
||||||
env::log_str(&format!("wormhole/{}#{}: migrate", file!(), line!(),));
|
// guardians: old_state.guardians,
|
||||||
Self {
|
// dups: old_state.dups,
|
||||||
guardians: old_state.guardians,
|
// emitters: old_state.emitters,
|
||||||
dups: old_state.dups,
|
// guardian_set_expirity: old_state.guardian_set_expirity,
|
||||||
emitters: old_state.emitters,
|
// guardian_set_index: old_state.guardian_set_index,
|
||||||
guardian_set_expirity: old_state.guardian_set_expirity,
|
// owner_pk: old_state.owner_pk,
|
||||||
guardian_set_index: old_state.guardian_set_index,
|
// upgrade_hash: old_state.upgrade_hash,
|
||||||
owner_pk: old_state.owner_pk,
|
// message_fee: old_state.message_fee,
|
||||||
upgrade_hash: old_state.upgrade_hash,
|
// bank: old_state.bank,
|
||||||
message_fee: old_state.message_fee,
|
// }
|
||||||
bank: old_state.bank,
|
// }
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// let result = await userAccount.functionCall({
|
// let result = await userAccount.functionCall({
|
||||||
|
|
|
@ -0,0 +1,144 @@
|
||||||
|
// npx pretty-quick
|
||||||
|
|
||||||
|
const nearAPI = require("near-api-js");
|
||||||
|
const BN = require("bn.js");
|
||||||
|
const fs = require("fs");
|
||||||
|
const fetch = require("node-fetch");
|
||||||
|
import { NodeHttpTransport } from "@improbable-eng/grpc-web-node-http-transport";
|
||||||
|
|
||||||
|
const { parseSeedPhrase, generateSeedPhrase } = require("near-seed-phrase");
|
||||||
|
|
||||||
|
function getConfig(env: any) {
|
||||||
|
switch (env) {
|
||||||
|
case "mainnet":
|
||||||
|
return {
|
||||||
|
networkId: "mainnet",
|
||||||
|
nodeUrl: "https://rpc.mainnet.near.org",
|
||||||
|
wormholeMasterAccount: "wormhole_crypto.near",
|
||||||
|
wormholeAccount: "contract.wormhole_crypto.near",
|
||||||
|
portalMasterAccount: "portalbridge.near",
|
||||||
|
portalAccount: "contract.portalbridge.near",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function initNear() {
|
||||||
|
let config = getConfig("mainnet");
|
||||||
|
|
||||||
|
let wormholeKeys = parseSeedPhrase(process.env.WORMHOLE_KEYS);
|
||||||
|
let portalKeys = parseSeedPhrase(process.env.PORTAL_KEYS);
|
||||||
|
|
||||||
|
let wormholeMasterKey = nearAPI.utils.KeyPair.fromString(
|
||||||
|
wormholeKeys["secretKey"]
|
||||||
|
);
|
||||||
|
let portalMasterKey = nearAPI.utils.KeyPair.fromString(
|
||||||
|
portalKeys["secretKey"]
|
||||||
|
);
|
||||||
|
|
||||||
|
let keyStore = new nearAPI.keyStores.InMemoryKeyStore();
|
||||||
|
keyStore.setKey(
|
||||||
|
config.networkId,
|
||||||
|
config.wormholeMasterAccount,
|
||||||
|
wormholeMasterKey
|
||||||
|
);
|
||||||
|
keyStore.setKey(config.networkId, config.wormholeAccount, wormholeMasterKey);
|
||||||
|
keyStore.setKey(
|
||||||
|
config.networkId,
|
||||||
|
config.portalMasterAccount,
|
||||||
|
portalMasterKey
|
||||||
|
);
|
||||||
|
keyStore.setKey(config.networkId, config.portalAccount, portalMasterKey);
|
||||||
|
|
||||||
|
let near = await nearAPI.connect({
|
||||||
|
deps: {
|
||||||
|
keyStore,
|
||||||
|
},
|
||||||
|
networkId: config.networkId,
|
||||||
|
nodeUrl: config.nodeUrl,
|
||||||
|
});
|
||||||
|
|
||||||
|
let wormholeMasterAccount = new nearAPI.Account(
|
||||||
|
near.connection,
|
||||||
|
config.wormholeMasterAccount
|
||||||
|
);
|
||||||
|
|
||||||
|
let portalMasterAccount = new nearAPI.Account(
|
||||||
|
near.connection,
|
||||||
|
config.portalMasterAccount
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
"wormhole account: " +
|
||||||
|
JSON.stringify(await wormholeMasterAccount.getAccountBalance())
|
||||||
|
);
|
||||||
|
console.log(
|
||||||
|
"portal account: " +
|
||||||
|
JSON.stringify(await portalMasterAccount.getAccountBalance())
|
||||||
|
);
|
||||||
|
|
||||||
|
const wormholeContract = await fs.readFileSync(
|
||||||
|
"contracts/wormhole/target/wasm32-unknown-unknown/release/near_wormhole.wasm"
|
||||||
|
);
|
||||||
|
const portalContract = await fs.readFileSync(
|
||||||
|
"contracts/token-bridge/target/wasm32-unknown-unknown/release/near_token_bridge.wasm"
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log("setting key for new wormhole contract");
|
||||||
|
|
||||||
|
keyStore.setKey(config.networkId, config.wormholeAccount, wormholeMasterKey);
|
||||||
|
keyStore.setKey(config.networkId, config.portalAccount, portalMasterKey);
|
||||||
|
|
||||||
|
console.log("Deploying core/wormhole contract: " + config.wormholeAccount);
|
||||||
|
|
||||||
|
let wormholeAccount = await wormholeMasterAccount.createAndDeployContract(
|
||||||
|
config.wormholeAccount,
|
||||||
|
wormholeMasterKey.getPublicKey(),
|
||||||
|
wormholeContract,
|
||||||
|
new BN("5000000000000000000000000")
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log("Deploying core/portal contract: " + config.portalAccount);
|
||||||
|
|
||||||
|
let portalAccount = await portalMasterAccount.createAndDeployContract(
|
||||||
|
config.portalAccount,
|
||||||
|
portalMasterKey.getPublicKey(),
|
||||||
|
portalContract,
|
||||||
|
new BN("12000000000000000000000000")
|
||||||
|
);
|
||||||
|
|
||||||
|
let result = await wormholeMasterAccount.functionCall({
|
||||||
|
contractId: config.wormholeAccount,
|
||||||
|
methodName: "boot_wormhole",
|
||||||
|
args: {
|
||||||
|
gset: 0,
|
||||||
|
addresses: ["58CC3AE5C097b213cE3c81979e1B9f9570746AA5"],
|
||||||
|
},
|
||||||
|
gas: 100000000000000,
|
||||||
|
});
|
||||||
|
|
||||||
|
result = await portalMasterAccount.functionCall({
|
||||||
|
contractId: config.portalAccount,
|
||||||
|
methodName: "boot_portal",
|
||||||
|
args: {
|
||||||
|
core: config.wormholeAccount,
|
||||||
|
},
|
||||||
|
gas: 100000000000000,
|
||||||
|
});
|
||||||
|
|
||||||
|
await wormholeMasterAccount.functionCall({
|
||||||
|
contractId: config.wormholeAccount,
|
||||||
|
methodName: "register_emitter",
|
||||||
|
args: { emitter: config.portalAccount },
|
||||||
|
attachedDeposit: new BN("30000000000000000000000"),
|
||||||
|
gas: new BN("100000000000000"),
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("deleting the master key from the token contract");
|
||||||
|
await portalAccount.deleteKey(portalMasterKey.getPublicKey());
|
||||||
|
|
||||||
|
console.log("deleting the master key from the wormhole contract");
|
||||||
|
await wormholeAccount.deleteKey(wormholeMasterKey.getPublicKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
initNear();
|
|
@ -1,4 +1,4 @@
|
||||||
[toolchain]
|
[toolchain]
|
||||||
channel = "nightly"
|
channel = "1.63"
|
||||||
targets = [ "wasm32-unknown-unknown" ]
|
targets = [ "wasm32-unknown-unknown" ]
|
||||||
profile = "default"
|
profile = "default"
|
||||||
|
|
|
@ -4,6 +4,14 @@ const bs58 = require("bs58");
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
const fetch = require("node-fetch");
|
const fetch = require("node-fetch");
|
||||||
import { NodeHttpTransport } from "@improbable-eng/grpc-web-node-http-transport";
|
import { NodeHttpTransport } from "@improbable-eng/grpc-web-node-http-transport";
|
||||||
|
const { createHash } = require('crypto');
|
||||||
|
import { TestLib } from "./testlib";
|
||||||
|
|
||||||
|
|
||||||
|
import {
|
||||||
|
ChainId,
|
||||||
|
CHAIN_ID_NEAR,
|
||||||
|
} from "@certusone/wormhole-sdk/lib/cjs/utils";
|
||||||
|
|
||||||
function getConfig(env: any) {
|
function getConfig(env: any) {
|
||||||
switch (env) {
|
switch (env) {
|
||||||
|
@ -22,6 +30,10 @@ function getConfig(env: any) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function hash(string: any) {
|
||||||
|
return createHash('sha256').update(string).digest('hex');
|
||||||
|
}
|
||||||
|
|
||||||
async function testDeploy() {
|
async function testDeploy() {
|
||||||
let config = getConfig(process.env.NEAR_ENV || "sandbox");
|
let config = getConfig(process.env.NEAR_ENV || "sandbox");
|
||||||
|
|
||||||
|
@ -56,7 +68,6 @@ async function testDeploy() {
|
||||||
);
|
);
|
||||||
|
|
||||||
let userKey = nearAPI.utils.KeyPair.fromRandom("ed25519");
|
let userKey = nearAPI.utils.KeyPair.fromRandom("ed25519");
|
||||||
keyStore.setKey(config.networkId, config.userAccount, userKey);
|
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
"creating a user account: " +
|
"creating a user account: " +
|
||||||
|
@ -70,43 +81,92 @@ async function testDeploy() {
|
||||||
userKey.getPublicKey(),
|
userKey.getPublicKey(),
|
||||||
new BN(10).pow(new BN(27))
|
new BN(10).pow(new BN(27))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// A whole new world...
|
||||||
|
keyStore = new nearAPI.keyStores.InMemoryKeyStore();
|
||||||
|
keyStore.setKey(config.networkId, config.userAccount, userKey);
|
||||||
|
|
||||||
|
near = await nearAPI.connect({
|
||||||
|
deps: {
|
||||||
|
keyStore,
|
||||||
|
},
|
||||||
|
networkId: config.networkId,
|
||||||
|
nodeUrl: config.nodeUrl,
|
||||||
|
});
|
||||||
|
|
||||||
const userAccount = new nearAPI.Account(near.connection, config.userAccount);
|
const userAccount = new nearAPI.Account(near.connection, config.userAccount);
|
||||||
|
|
||||||
const wormholeContract = await fs.readFileSync(
|
const wormholeContract = await fs.readFileSync(
|
||||||
"../contracts/wormhole/target/wasm32-unknown-unknown/release/near_wormhole.wasm"
|
"../contracts/wormhole/target/wasm32-unknown-unknown/release/near_wormhole.wasm"
|
||||||
);
|
);
|
||||||
|
|
||||||
//console.log("sending money to cover the cost of deploying this contract.. so that we fail for the right reasons");
|
let h = hash(wormholeContract);
|
||||||
//await userAccount.sendMoney(config.wormholeAccount, new BN("10000000000000000000000000"));
|
|
||||||
|
|
||||||
keyStore.setKey(config.networkId, config.wormholeAccount, masterKey);
|
let ts = new TestLib();
|
||||||
|
let seq = 1;
|
||||||
|
let vaa = ts.genCoreUpdate(ts.singleGuardianPrivKey, 0, 0, seq, CHAIN_ID_NEAR, h);
|
||||||
|
|
||||||
let wormholeAccount = new nearAPI.Account(
|
let wormholeAccount = new nearAPI.Account(
|
||||||
near.connection,
|
near.connection,
|
||||||
config.wormholeAccount
|
config.wormholeAccount
|
||||||
);
|
);
|
||||||
|
|
||||||
try {
|
console.log("submitting vaa");
|
||||||
console.log("redeploying wormhole contract using standard deployment API");
|
let result = await userAccount.functionCall({
|
||||||
let resp = await wormholeAccount.deployContract(wormholeContract);
|
contractId: config.wormholeAccount,
|
||||||
console.log(resp);
|
methodName: "submit_vaa",
|
||||||
console.log("This should have thrown a exception..");
|
args: { vaa: vaa },
|
||||||
process.exit(1);
|
attachedDeposit: "12500000000000000000000",
|
||||||
} catch {
|
gas: new BN("150000000000000"),
|
||||||
console.log("Exception thrown.. nice.. we dont suck");
|
});
|
||||||
}
|
|
||||||
|
|
||||||
console.log("calling upgradeContract");
|
console.log("calling upgradeContract");
|
||||||
let result = await userAccount.functionCall({
|
|
||||||
|
result = await userAccount.functionCall({
|
||||||
contractId: config.wormholeAccount,
|
contractId: config.wormholeAccount,
|
||||||
methodName: "update_contract",
|
methodName: "update_contract",
|
||||||
args: wormholeContract,
|
args: wormholeContract,
|
||||||
attachedDeposit: "12500000000000000000000",
|
attachedDeposit: "5279790000000000000000000",
|
||||||
gas: 300000000000000,
|
gas: 300000000000000,
|
||||||
});
|
});
|
||||||
console.log("done");
|
console.log("done");
|
||||||
|
|
||||||
console.log(result);
|
const tokenContract = await fs.readFileSync(
|
||||||
|
"../contracts/token-bridge/target/wasm32-unknown-unknown/release/near_token_bridge.wasm"
|
||||||
|
);
|
||||||
|
|
||||||
|
h = hash(tokenContract);
|
||||||
|
seq = seq + 1
|
||||||
|
vaa = ts.genTokenUpdate(ts.singleGuardianPrivKey, 0, 0, seq, CHAIN_ID_NEAR, h);
|
||||||
|
|
||||||
|
console.log("submitting vaa");
|
||||||
|
result = await userAccount.functionCall({
|
||||||
|
contractId: config.tokenAccount,
|
||||||
|
methodName: "submit_vaa",
|
||||||
|
args: { vaa: vaa },
|
||||||
|
attachedDeposit: "12500000000000000000000",
|
||||||
|
gas: new BN("150000000000000"),
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("submitting vaa again");
|
||||||
|
result = await userAccount.functionCall({
|
||||||
|
contractId: config.tokenAccount,
|
||||||
|
methodName: "submit_vaa",
|
||||||
|
args: { vaa: vaa },
|
||||||
|
attachedDeposit: "12500000000000000000000",
|
||||||
|
gas: new BN("150000000000000"),
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("calling upgradeContract on the token bridge");
|
||||||
|
|
||||||
|
result = await userAccount.functionCall({
|
||||||
|
contractId: config.tokenAccount,
|
||||||
|
methodName: "update_contract",
|
||||||
|
args: tokenContract,
|
||||||
|
attachedDeposit: "22797900000000000000000000",
|
||||||
|
gas: 300000000000000,
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
testDeploy();
|
testDeploy();
|
||||||
|
|
|
@ -247,6 +247,87 @@ export class TestLib {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
genCoreUpdate(
|
||||||
|
signers: any,
|
||||||
|
guardianSet: number,
|
||||||
|
nonce: number,
|
||||||
|
seq: number,
|
||||||
|
tchain: number,
|
||||||
|
hash: string
|
||||||
|
) {
|
||||||
|
const b = [
|
||||||
|
"0x",
|
||||||
|
this.zeroBytes.slice(0, 28 * 2),
|
||||||
|
this.encoder("uint8", this.ord("C")),
|
||||||
|
this.encoder("uint8", this.ord("o")),
|
||||||
|
this.encoder("uint8", this.ord("r")),
|
||||||
|
this.encoder("uint8", this.ord("e")),
|
||||||
|
this.encoder("uint8", 1),
|
||||||
|
this.encoder("uint16", tchain),
|
||||||
|
hash
|
||||||
|
];
|
||||||
|
|
||||||
|
let emitter = "0x" + this.zeroBytes.slice(0, 31 * 2) + "04";
|
||||||
|
|
||||||
|
var seconds = Math.floor(new Date().getTime() / 1000.0);
|
||||||
|
|
||||||
|
return this.createSignedVAA(
|
||||||
|
guardianSet,
|
||||||
|
signers,
|
||||||
|
seconds,
|
||||||
|
nonce,
|
||||||
|
1,
|
||||||
|
emitter,
|
||||||
|
seq,
|
||||||
|
32,
|
||||||
|
b.join("")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
genTokenUpdate(
|
||||||
|
signers: any,
|
||||||
|
guardianSet: number,
|
||||||
|
nonce: number,
|
||||||
|
seq: number,
|
||||||
|
tchain: number,
|
||||||
|
hash: string
|
||||||
|
) {
|
||||||
|
const b = [
|
||||||
|
"0x",
|
||||||
|
this.zeroBytes.slice(0, (32 - 11) * 2),
|
||||||
|
this.encoder("uint8", this.ord("T")),
|
||||||
|
this.encoder("uint8", this.ord("o")),
|
||||||
|
this.encoder("uint8", this.ord("k")),
|
||||||
|
this.encoder("uint8", this.ord("e")),
|
||||||
|
this.encoder("uint8", this.ord("n")),
|
||||||
|
this.encoder("uint8", this.ord("B")),
|
||||||
|
this.encoder("uint8", this.ord("r")),
|
||||||
|
this.encoder("uint8", this.ord("i")),
|
||||||
|
this.encoder("uint8", this.ord("d")),
|
||||||
|
this.encoder("uint8", this.ord("g")),
|
||||||
|
this.encoder("uint8", this.ord("e")),
|
||||||
|
this.encoder("uint8", 2),
|
||||||
|
this.encoder("uint16", tchain),
|
||||||
|
hash
|
||||||
|
];
|
||||||
|
|
||||||
|
let emitter = "0x" + this.zeroBytes.slice(0, 31 * 2) + "04";
|
||||||
|
|
||||||
|
var seconds = Math.floor(new Date().getTime() / 1000.0);
|
||||||
|
|
||||||
|
return this.createSignedVAA(
|
||||||
|
guardianSet,
|
||||||
|
signers,
|
||||||
|
seconds,
|
||||||
|
nonce,
|
||||||
|
1,
|
||||||
|
emitter,
|
||||||
|
seq,
|
||||||
|
32,
|
||||||
|
b.join("")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
getTokenEmitter(chain: number): string {
|
getTokenEmitter(chain: number): string {
|
||||||
if (chain === CHAIN_ID_SOLANA) {
|
if (chain === CHAIN_ID_SOLANA) {
|
||||||
return "c69a1b1a65dd336bf1df6a77afb501fc25db7fc0938cb08595a9ef473265cb4f";
|
return "c69a1b1a65dd336bf1df6a77afb501fc25db7fc0938cb08595a9ef473265cb4f";
|
||||||
|
|
Loading…
Reference in New Issue