ABI's from contract/out files

This commit is contained in:
Tim
2024-07-03 16:12:21 -04:00
parent 930ba86ef3
commit 7868195d5c
5 changed files with 45 additions and 83 deletions

63
abi.js
View File

@@ -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))
}

25
contract.js Normal file
View File

@@ -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)
}

View File

@@ -1,7 +1,7 @@
import {ethers} from "ethers"; import {ethers} from "ethers";
import {getProvider} from "./blockchain.js"; import {getProvider} from "./blockchain.js";
import {chainInfo} from "./chain.js"; import {chainInfo} from "./chain.js";
import {mockErc20Abi} from "./abi.js"; import {mockERC20Contract} from "./contract.js";
export async function gib( chainId, owner, vault, tokenAmounts ) { export async function gib( chainId, owner, vault, tokenAmounts ) {
@@ -28,7 +28,7 @@ export async function gib( chainId, owner, vault, tokenAmounts ) {
} }
else { else {
console.log(`sending ${token} coin to ${vault} +${amount}`) 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 [coinAddr, usdAddr] = info.mockCoins
const signer = await provider.getSigner() const signer = await provider.getSigner()
console.log('faucet minting tokens to', vault) console.log('faucet minting tokens to', vault)
await new ethers.Contract(coinAddr, mockErc20Abi, signer).mint(vault, 10n *10n**18n) await (await mockERC20Contract(coinAddr, signer)).mint(vault, 10n *10n**18n)
await new ethers.Contract(usdAddr, mockErc20Abi, signer).mint(vault, 10_000n *10n**6n) await (await mockERC20Contract(usdAddr, signer)).mint(vault, 10_000n *10n**6n)
} }
} }
} }

View File

@@ -3,8 +3,8 @@
// todo load standard known tokens // todo load standard known tokens
import {ethers} from "ethers"; import {ethers} from "ethers";
import {erc20Abi} from "./abi.js";
import {getProvider} from "./blockchain.js"; import {getProvider} from "./blockchain.js";
import {newContract} from "../web/src/blockchain/contract.js";
const std_arbitrum_tokens = {} const std_arbitrum_tokens = {}
const tokens = { const tokens = {
@@ -13,8 +13,8 @@ const tokens = {
1337: {}, 1337: {},
} }
export function erc20(chainId, addr, provider=null) { export async function erc20(chainId, addr, provider=null) {
return new ethers.Contract(addr, erc20Abi, provider?provider:getProvider(chainId)); return await newContract(addr, 'IERC20Metadata', provider?provider:getProvider(chainId));
} }
let _loggedNoTokensForChain = false let _loggedNoTokensForChain = false
@@ -32,9 +32,9 @@ export async function lookupToken(chainId, address) {
let result = chainTokens[address] let result = chainTokens[address]
// console.log('found', result) // console.log('found', result)
if (result === undefined) { if (result === undefined) {
// todo look in tokens project // todo look in tokens project?
const addr = ethers.getAddress(address) 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()]) let [name, symbol, decimals] = await Promise.all([token.name(), token.symbol(), token.decimals()])
name = Number(name) name = Number(name)
decimals = Number(decimals) decimals = Number(decimals)

View File

@@ -1,13 +1,9 @@
import {ethers} from "ethers"; import {ethers} from "ethers";
import {getAbi} from "./abi.js";
import {getProvider, getSigner} from "./blockchain.js"; import {getProvider, getSigner} from "./blockchain.js";
import {vaultBalances, vaults} from './cache.js'; import {vaultBalances, vaults} from './cache.js';
import {chainInfo, VAULT_INIT_CODE_HASH} from "./chain.js"; import {chainInfo, VAULT_INIT_CODE_HASH} from "./chain.js";
import {sendVaultOrders} from "./order.js"; import {sendVaultOrders} from "./order.js";
import {newContract} from "./contract.js";
const vaultAbi = await getAbi('Vault')
const factoryAbi = await getAbi('VaultFactory')
export function vaultAddress(chainId, owner, num=0) { export function vaultAddress(chainId, owner, num=0) {
@@ -96,22 +92,26 @@ async function createVault(chainId, owner, num) {
const signer = getSigner(chainId); const signer = getSigner(chainId);
const factory = chainInfo[chainId].factory; const factory = chainInfo[chainId].factory;
console.log('createVault', chainId, owner, num, 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) const vaultAddr = vaultAddress(chainId, owner, num)
console.log(' ==>', vaultAddr ) console.log(' ==>', vaultAddr )
try { try {
const tx = await deployer.deployVault(owner, num) 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}`) console.log(`deploying vault for ${owner} #${num} with tx ${tx.hash}`)
await tx.wait() const result = await tx.wait()
if (result.status !== 1) {
// noinspection ExceptionCaughtLocallyJS
throw Error(`Vault deployment reverted. tx ${tx.hash}`)
}
} }
catch (e) { catch (e) {
const vault = new ethers.Contract(vaultAddr, vaultAbi, getProvider(chainId)) const vault = await newContract(vaultAddr, 'IVault', getProvider(chainId))
try { try {
const ver = await vault.version() const ver = await vault.version()
console.log(`vault already deployed at ${vaultAddr} with version ${ver}`) console.log(`vault already deployed at ${vaultAddr} with version ${ver}`)
} }
catch (e2) { catch (e2) {
console.error('could not deploy vault:', e2) console.error('could not deploy vault:', e)
return null return null
} }
} }