fix(smart-contracts): add increased gas limit estimation (#3371)

This commit is contained in:
Matthew Russell 2023-04-04 11:41:11 -07:00 committed by GitHub
parent 5fd93ee9c8
commit bde7a9fbf9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 176 additions and 55 deletions

View File

@ -1,6 +1,7 @@
import { ethers } from 'ethers'; import { ethers } from 'ethers';
import { hexlify } from 'ethers/lib/utils'; import { hexlify } from 'ethers/lib/utils';
import abi from '../abis/claim_abi.json'; import abi from '../abis/claim_abi.json';
import { calcGasBuffer } from '../utils';
export const UNSPENT_CODE = '0x0000000000000000000000000000000000000000'; export const UNSPENT_CODE = '0x0000000000000000000000000000000000000000';
export const SPENT_CODE = '0x0000000000000000000000000000000000000001'; export const SPENT_CODE = '0x0000000000000000000000000000000000000001';
@ -42,7 +43,7 @@ export class Claim {
* was performed and mined beforehand * was performed and mined beforehand
* @return {Promise<boolean>} * @return {Promise<boolean>}
*/ */
public claim({ public async claim({
amount, amount,
tranche, tranche,
expiry, expiry,
@ -61,10 +62,8 @@ export class Claim {
r: string; r: string;
s: string; s: string;
}): Promise<ethers.ContractTransaction> { }): Promise<ethers.ContractTransaction> {
return this.contract[ const method = target != null ? 'claim_targeted' : 'claim_untargeted';
target != null ? 'claim_targeted' : 'claim_untargeted' const args = [
](
...[
{ r, s, v }, { r, s, v },
{ {
amount, amount,
@ -73,8 +72,10 @@ export class Claim {
}, },
hexlify(country), hexlify(country),
target, target,
].filter(Boolean) ].filter(Boolean);
); const res = await this.contract.estimateGas[method](...args);
const gasLimit = calcGasBuffer(res);
return this.contract[method](...args, { gasLimit });
} }
/** /**

View File

@ -1,6 +1,7 @@
import type { BigNumber } from 'ethers'; import type { BigNumber } from 'ethers';
import { ethers } from 'ethers'; import { ethers } from 'ethers';
import abi from '../abis/erc20_bridge_abi.json'; import abi from '../abis/erc20_bridge_abi.json';
import { calcGasBuffer } from '../utils';
export class CollateralBridge { export class CollateralBridge {
public contract: ethers.Contract; public contract: ethers.Contract;
@ -13,8 +14,20 @@ export class CollateralBridge {
this.contract = new ethers.Contract(address, abi, signerOrProvider); this.contract = new ethers.Contract(address, abi, signerOrProvider);
} }
deposit_asset(assetSource: string, amount: string, vegaPublicKey: string) { async deposit_asset(
return this.contract.deposit_asset(assetSource, amount, vegaPublicKey); assetSource: string,
amount: string,
vegaPublicKey: string
) {
const res = await this.contract.estimateGas.deposit_asset(
assetSource,
amount,
vegaPublicKey
);
const gasLimit = calcGasBuffer(res);
return this.contract.deposit_asset(assetSource, amount, vegaPublicKey, {
gasLimit,
});
} }
get_asset_source(vegaAssetId: string) { get_asset_source(vegaAssetId: string) {
return this.contract.get_asset_source(vegaAssetId); return this.contract.get_asset_source(vegaAssetId);
@ -37,7 +50,7 @@ export class CollateralBridge {
default_withdraw_delay() { default_withdraw_delay() {
return this.contract.default_withdraw_delay(); return this.contract.default_withdraw_delay();
} }
list_asset( async list_asset(
address: string, address: string,
vegaAssetId: string, vegaAssetId: string,
lifetimeLimit: string, lifetimeLimit: string,
@ -45,7 +58,7 @@ export class CollateralBridge {
nonce: string, nonce: string,
signatures: string signatures: string
) { ) {
return this.contract.list_asset( const res = await this.contract.estimateGas.list_asset(
address, address,
vegaAssetId, vegaAssetId,
lifetimeLimit, lifetimeLimit,
@ -53,8 +66,20 @@ export class CollateralBridge {
nonce, nonce,
signatures signatures
); );
const gasLimit = calcGasBuffer(res);
return this.contract.list_asset(
address,
vegaAssetId,
lifetimeLimit,
withdraw_threshold,
nonce,
signatures,
{
gasLimit,
} }
withdraw_asset( );
}
async withdraw_asset(
assetSource: string, assetSource: string,
amount: string, amount: string,
target: string, target: string,
@ -62,7 +87,7 @@ export class CollateralBridge {
nonce: string, nonce: string,
signatures: string signatures: string
) { ) {
return this.contract.withdraw_asset( const res = await this.contract.estimateGas.withdraw_asset(
assetSource, assetSource,
amount, amount,
target, target,
@ -70,6 +95,18 @@ export class CollateralBridge {
nonce, nonce,
signatures signatures
); );
const gasLimit = calcGasBuffer(res);
return this.contract.withdraw_asset(
assetSource,
amount,
target,
creation,
nonce,
signatures,
{
gasLimit,
}
);
} }
is_stopped() { is_stopped() {

View File

@ -1,5 +1,6 @@
import { ethers } from 'ethers'; import { ethers } from 'ethers';
import abi from '../abis/multisig_abi.json'; import abi from '../abis/multisig_abi.json';
import { calcGasBuffer } from '../utils';
export class MultisigControl { export class MultisigControl {
public contract: ethers.Contract; public contract: ethers.Contract;
@ -13,12 +14,20 @@ export class MultisigControl {
this.address = address; this.address = address;
} }
add_signer(newSigner: string, nonce: string, signatures: string) { async add_signer(newSigner: string, nonce: string, signatures: string) {
return this.contract.add_signer(newSigner, nonce, signatures); const res = await this.contract.estimateGas.add_signer(
newSigner,
nonce,
signatures
);
const gasLimit = calcGasBuffer(res);
return this.contract.add_signer(newSigner, nonce, signatures, { gasLimit });
} }
burn_nonce(nonce: string, signatures: string) { async burn_nonce(nonce: string, signatures: string) {
return this.contract.burn_nonce(nonce, signatures); const res = await this.contract.estimateGas.burn_nonce(nonce, signatures);
const gasLimit = calcGasBuffer(res);
return this.contract.burn_nonce(nonce, signatures, { gasLimit });
} }
get_current_threshold() { get_current_threshold() {
@ -37,19 +46,43 @@ export class MultisigControl {
return this.contract.is_valid_signer(signerAddress); return this.contract.is_valid_signer(signerAddress);
} }
remove_signer(oldSigner: string, nonce: string, signatures: string) { async remove_signer(oldSigner: string, nonce: string, signatures: string) {
return this.contract.remove_signer(oldSigner, nonce, signatures); const res = await this.contract.estimateGas.remove_signer(
oldSigner,
nonce,
signatures
);
const gasLimit = calcGasBuffer(res);
return this.contract.remove_signer(oldSigner, nonce, signatures, {
gasLimit,
});
} }
set_threshold(newThreshold: string, nonce: string, signatures: string) { async set_threshold(newThreshold: string, nonce: string, signatures: string) {
return this.contract.set_threshold(newThreshold, nonce, signatures); const res = await this.contract.estimateGas.set_threshold(
newThreshold,
nonce,
signatures
);
const gasLimit = calcGasBuffer(res);
return this.contract.set_threshold(newThreshold, nonce, signatures, {
gasLimit,
});
} }
signers(address: string) { signers(address: string) {
return this.contract.signers(address); return this.contract.signers(address);
} }
verify_signatures(nonce: string, message: string, signatures: string) { async verify_signatures(nonce: string, message: string, signatures: string) {
return this.contract.verify_signatures(nonce, message, signatures); const res = await this.contract.estimateGas.verify_signatures(
nonce,
message,
signatures
);
const gasLimit = calcGasBuffer(res);
return this.contract.verify_signatures(nonce, message, signatures, {
gasLimit,
});
} }
} }

View File

@ -1,6 +1,6 @@
import { ethers } from 'ethers'; import { ethers } from 'ethers';
import abi from '../abis/staking_abi.json'; import abi from '../abis/staking_abi.json';
import { prepend0x } from '../utils'; import { calcGasBuffer, prepend0x } from '../utils';
export class StakingBridge { export class StakingBridge {
public contract: ethers.Contract; public contract: ethers.Contract;
@ -13,20 +13,41 @@ export class StakingBridge {
this.contract = new ethers.Contract(address, abi, signerOrProvider); this.contract = new ethers.Contract(address, abi, signerOrProvider);
this.address = address; this.address = address;
} }
async stake(amount: string, vegaPublicKey: string) {
const key = prepend0x(vegaPublicKey);
const res = await this.contract.estimateGas.stake(amount, key);
const gasLimit = calcGasBuffer(res);
return this.contract.stake(amount, key, {
gasLimit,
});
}
stake(amount: string, vegaPublicKey: string) { async remove_stake(amount: string, vegaPublicKey: string) {
return this.contract.stake(amount, prepend0x(vegaPublicKey)); const key = prepend0x(vegaPublicKey);
const res = await this.contract.estimateGas.remove_stake(amount, key);
const gasLimit = calcGasBuffer(res);
return this.contract.remove_stake(amount, key, {
gasLimit,
});
} }
remove_stake(amount: string, vegaPublicKey: string) {
return this.contract.remove_stake(amount, prepend0x(vegaPublicKey)); async transfer_stake(
} amount: string,
transfer_stake(amount: string, newAddress: string, vegaPublicKey: string) { newAddress: string,
return this.contract.transfer_stake( vegaPublicKey: string
) {
const key = prepend0x(vegaPublicKey);
const res = await this.contract.estimateGas.transfer_stake(
amount, amount,
newAddress, newAddress,
prepend0x(vegaPublicKey) key
); );
const gasLimit = calcGasBuffer(res);
return this.contract.transfer_stake(amount, newAddress, key, {
gasLimit,
});
} }
staking_token() { staking_token() {
return this.contract.staking_token(); return this.contract.staking_token();
} }

View File

@ -1,6 +1,7 @@
import type { BigNumber } from 'ethers'; import type { BigNumber } from 'ethers';
import { ethers } from 'ethers'; import { ethers } from 'ethers';
import erc20AbiFaucetable from '../abis/erc20_abi_faucet.json'; import erc20AbiFaucetable from '../abis/erc20_abi_faucet.json';
import { calcGasBuffer } from '../utils';
export class TokenFaucetable { export class TokenFaucetable {
public contract: ethers.Contract; public contract: ethers.Contract;
@ -27,13 +28,17 @@ export class TokenFaucetable {
allowance(owner: string, spender: string): Promise<BigNumber> { allowance(owner: string, spender: string): Promise<BigNumber> {
return this.contract.allowance(owner, spender); return this.contract.allowance(owner, spender);
} }
approve(spender: string, amount: string) { async approve(spender: string, amount: string) {
return this.contract.approve(spender, amount); const res = await this.contract.estimateGas.approve(spender, amount);
const gasLimit = calcGasBuffer(res);
return this.contract.approve(spender, amount, { gasLimit });
} }
decimals(): Promise<number> { decimals(): Promise<number> {
return this.contract.decimals(); return this.contract.decimals();
} }
faucet() { async faucet() {
return this.contract.faucet(); const res = await this.contract.estimateGas.faucet();
const gasLimit = calcGasBuffer(res);
return this.contract.faucet({ gasLimit });
} }
} }

View File

@ -1,6 +1,6 @@
import { ethers } from 'ethers'; import { ethers } from 'ethers';
import abi from '../abis/vesting_abi.json'; import abi from '../abis/vesting_abi.json';
import { prepend0x } from '../utils'; import { calcGasBuffer, prepend0x } from '../utils';
export class TokenVesting { export class TokenVesting {
public contract: ethers.Contract; public contract: ethers.Contract;
@ -13,12 +13,21 @@ export class TokenVesting {
this.contract = new ethers.Contract(address, abi, signerOrProvider); this.contract = new ethers.Contract(address, abi, signerOrProvider);
this.address = address; this.address = address;
} }
async stake_tokens(amount: string, vegaPublicKey: string) {
stake_tokens(amount: string, vegaPublicKey: string) { const key = prepend0x(vegaPublicKey);
return this.contract.stake_tokens(amount, prepend0x(vegaPublicKey)); const res = await this.contract.estimateGas.stake_tokens(amount, key);
const gasLimit = calcGasBuffer(res);
return this.contract.stake_tokens(amount, key, {
gasLimit,
});
} }
remove_stake(amount: string, vegaPublicKey: string) { async remove_stake(amount: string, vegaPublicKey: string) {
return this.contract.remove_stake(amount, prepend0x(vegaPublicKey)); const key = prepend0x(vegaPublicKey);
const res = await this.contract.estimateGas.remove_stake(amount, key);
const gasLimit = calcGasBuffer(res);
return this.contract.remove_stake(amount, key, {
gasLimit,
});
} }
stake_balance(address: string, vegaPublicKey: string) { stake_balance(address: string, vegaPublicKey: string) {
return this.contract.stake_balance(address, prepend0x(vegaPublicKey)); return this.contract.stake_balance(address, prepend0x(vegaPublicKey));
@ -38,7 +47,13 @@ export class TokenVesting {
user_total_all_tranches(address: string) { user_total_all_tranches(address: string) {
return this.contract.user_total_all_tranches(address); return this.contract.user_total_all_tranches(address);
} }
withdraw_from_tranche(trancheId: number) { async withdraw_from_tranche(trancheId: number) {
return this.contract.withdraw_from_tranche(trancheId); const res = await this.contract.estimateGas.withdraw_from_tranche(
trancheId
);
const gasLimit = calcGasBuffer(res);
return this.contract.withdraw_from_tranche(trancheId, {
gasLimit,
});
} }
} }

View File

@ -1,6 +1,7 @@
import type { BigNumber } from 'ethers'; import type { BigNumber } from 'ethers';
import { ethers } from 'ethers'; import { ethers } from 'ethers';
import erc20Abi from '../abis/erc20_abi.json'; import erc20Abi from '../abis/erc20_abi.json';
import { calcGasBuffer } from '../utils';
export class Token { export class Token {
public contract: ethers.Contract; public contract: ethers.Contract;
@ -23,13 +24,15 @@ export class Token {
allowance(owner: string, spender: string): Promise<BigNumber> { allowance(owner: string, spender: string): Promise<BigNumber> {
return this.contract.allowance(owner, spender); return this.contract.allowance(owner, spender);
} }
approve(spender: string, amount: string) { async approve(spender: string, amount: string) {
return this.contract.approve(spender, amount); const res = await this.contract.estimateGas.approve(spender, amount);
const gasLimit = calcGasBuffer(res);
return this.contract.approve(spender, amount, { gasLimit });
} }
decimals(): Promise<number> { decimals(): Promise<number> {
return this.contract.decimals(); return this.contract.decimals();
} }
faucet() { async faucet() {
/* No op */ /* No op */
} }
} }

View File

@ -0,0 +1,5 @@
import type { BigNumber as EthersBigNumber } from 'ethers';
export function calcGasBuffer(value: EthersBigNumber): EthersBigNumber {
return value.mul(120).div(100);
}

View File

@ -1 +1,2 @@
export * from './calc-gas-buffer';
export * from './prepend-0x'; export * from './prepend-0x';