diff --git a/abi.js b/abi.js deleted file mode 100644 index ed4e008..0000000 --- a/abi.js +++ /dev/null @@ -1,63 +0,0 @@ -import {ethers} from "ethers"; -import {readFile} from "./misc.js"; - -const ABI_BASE_PATH = '../contract/out' - - -export const erc20Abi = [ - 'function name() view returns (string)', - 'function symbol() view returns (string)', - 'function decimals() view returns (uint8)', - 'function totalSupply() view returns (uint256)', - 'function balanceOf(address) view returns (uint256)', - 'function transfer(address,uint256) returns (bool)', - 'function transferFrom(address,address,uint256) returns (bool)', - 'function approve(address,uint256) returns (bool success)', - 'function allowance(address,address) view returns (uint256)', - 'event Transfer(address indexed,address indexed,uint256)', - 'event Approval(address indexed,address indexed,uint256)', -] - - -export const mockErc20Abi = [ - ...erc20Abi, - 'function mint(address,uint256)', -] - - -const factoryAbi = [ - 'function deployVault(address owner, uint8 num) returns (address vault)', - 'event VaultCreated( address deployer, address owner )', -] - - -export const abi = { - 'ERC20': erc20Abi, - 'VaultFactory': factoryAbi, -} - - -export async function getAbi(className) { - let found = abi[className] - if (found === undefined) { - console.log('warning: loading ABI from filesystem for '+className) - let data = await readFile(ABI_BASE_PATH + `/${className}.sol/${className}.json`) - // Tricky code to handle proxy Vault where interface file is needed instead of class file - if (className == 'Vault') { - try { - data = await readFile(ABI_BASE_PATH + `/I${className}.sol/I${className}.json`) - } - catch (e) { - if (e.code !== 'ENOENT') throw e; - } - } - found = JSON.parse(data.toString())['abi'] - abi[className] = found - } - return found -} - - -export async function getInterface(className) { - return new ethers.Interface(await getAbi(className)) -} diff --git a/contract.js b/contract.js new file mode 100644 index 0000000..fb3c552 --- /dev/null +++ b/contract.js @@ -0,0 +1,25 @@ +import {AbiFileCache} from "../web/src/common.js" +import {ethers} from "ethers"; + +const ABI_BASE_URL = '../contract/out/' + +const abiCache = new AbiFileCache(ABI_BASE_URL) + + +export async function getAbi(className) { + return await abiCache.get(className) +} + + +export async function newContract(addr, name, provider) { + const abi = await getAbi(name); + return new ethers.Contract(addr, abi, provider) +} + +export async function mockERC20Contract(addr, provider) { + return await newContract(addr, 'MockERC20', provider) +} + +export async function erc20Contract(addr, provider) { + return await newContract(addr, 'IERC20Metadata', provider) +} diff --git a/faucet.js b/faucet.js index 0e7c843..09ce7e5 100644 --- a/faucet.js +++ b/faucet.js @@ -1,7 +1,7 @@ import {ethers} from "ethers"; import {getProvider} from "./blockchain.js"; import {chainInfo} from "./chain.js"; -import {mockErc20Abi} from "./abi.js"; +import {mockERC20Contract} from "./contract.js"; export async function gib( chainId, owner, vault, tokenAmounts ) { @@ -28,7 +28,7 @@ export async function gib( chainId, owner, vault, tokenAmounts ) { } else { console.log(`sending ${token} coin to ${vault} +${amount}`) - await new ethers.Contract(token, mockErc20Abi, signer).mint(vault, amount) + await (await mockERC20Contract(token,signer)).mint(vault, amount) } } @@ -37,8 +37,8 @@ export async function gib( chainId, owner, vault, tokenAmounts ) { const [coinAddr, usdAddr] = info.mockCoins const signer = await provider.getSigner() console.log('faucet minting tokens to', vault) - await new ethers.Contract(coinAddr, mockErc20Abi, signer).mint(vault, 10n *10n**18n) - await new ethers.Contract(usdAddr, mockErc20Abi, signer).mint(vault, 10_000n *10n**6n) + await (await mockERC20Contract(coinAddr, signer)).mint(vault, 10n *10n**18n) + await (await mockERC20Contract(usdAddr, signer)).mint(vault, 10_000n *10n**6n) } } } diff --git a/token.js b/token.js index 6635e73..eefad29 100644 --- a/token.js +++ b/token.js @@ -3,8 +3,8 @@ // todo load standard known tokens import {ethers} from "ethers"; -import {erc20Abi} from "./abi.js"; import {getProvider} from "./blockchain.js"; +import {newContract} from "../web/src/blockchain/contract.js"; const std_arbitrum_tokens = {} const tokens = { @@ -13,8 +13,8 @@ const tokens = { 1337: {}, } -export function erc20(chainId, addr, provider=null) { - return new ethers.Contract(addr, erc20Abi, provider?provider:getProvider(chainId)); +export async function erc20(chainId, addr, provider=null) { + return await newContract(addr, 'IERC20Metadata', provider?provider:getProvider(chainId)); } let _loggedNoTokensForChain = false @@ -32,9 +32,9 @@ export async function lookupToken(chainId, address) { let result = chainTokens[address] // console.log('found', result) if (result === undefined) { - // todo look in tokens project + // todo look in tokens project? const addr = ethers.getAddress(address) - const token = erc20(chainId, addr) + const token = await erc20(chainId, addr) let [name, symbol, decimals] = await Promise.all([token.name(), token.symbol(), token.decimals()]) name = Number(name) decimals = Number(decimals) diff --git a/vault.js b/vault.js index 1a815ac..c342fe7 100644 --- a/vault.js +++ b/vault.js @@ -1,13 +1,9 @@ import {ethers} from "ethers"; -import {getAbi} from "./abi.js"; import {getProvider, getSigner} from "./blockchain.js"; import {vaultBalances, vaults} from './cache.js'; import {chainInfo, VAULT_INIT_CODE_HASH} from "./chain.js"; import {sendVaultOrders} from "./order.js"; - - -const vaultAbi = await getAbi('Vault') -const factoryAbi = await getAbi('VaultFactory') +import {newContract} from "./contract.js"; export function vaultAddress(chainId, owner, num=0) { @@ -96,22 +92,26 @@ async function createVault(chainId, owner, num) { const signer = getSigner(chainId); const factory = chainInfo[chainId].factory; console.log('createVault', chainId, owner, num, factory ) - const deployer = new ethers.Contract(factory, factoryAbi, signer) + const deployer = await newContract(factory, 'IVaultFactory', signer) const vaultAddr = vaultAddress(chainId, owner, num) console.log(' ==>', vaultAddr ) try { - const tx = await deployer.deployVault(owner, num) - // console.log(`deploying vault for ${owner} #${num} with tx ${tx.hash}`) - await tx.wait() + const tx = await deployer['deployVault(address,uint8)'](owner, num) // must specify which deployVault() to call + console.log(`deploying vault for ${owner} #${num} with tx ${tx.hash}`) + const result = await tx.wait() + if (result.status !== 1) { + // noinspection ExceptionCaughtLocallyJS + throw Error(`Vault deployment reverted. tx ${tx.hash}`) + } } catch (e) { - const vault = new ethers.Contract(vaultAddr, vaultAbi, getProvider(chainId)) + const vault = await newContract(vaultAddr, 'IVault', getProvider(chainId)) try { const ver = await vault.version() console.log(`vault already deployed at ${vaultAddr} with version ${ver}`) } catch (e2) { - console.error('could not deploy vault:', e2) + console.error('could not deploy vault:', e) return null } }