I get errors when trying to transfer tokens using a Defender Relayer on BNB chain testnet.
Details
I deployed a ERC2771Forwarder
and deployed a token that inherits ERC2771Context
, passing the forwarder address into its constructor.
I ran code similar to the example at https://docs.openzeppelin.com/defender/v2/manage/relayers#using-ethers.js
I got this error output:
<ref *1> Error: cannot estimate gas; transaction may fail or may require manual gas limit [ See: https://links.ethers.org/v5-errors-UNPREDICTABLE_GAS_LIMIT ] (error={"reason":"execution reverted","code":"UNPREDICTABLE_GAS_LIMIT","method":"estimateGas","transaction":{"from":"0x14f9A42ED153dcD817265f57308FFD11f7FE8DBa","to":"0x6C83356994D60cD88116320B08B43fa198fA5D02","data":"0xa9059cbb000000000000000000000000eb2e452fc167b5bb948c6fc2c9215ce7f4064692000000000000000000000000000000000000000000000000016345785d8a0000","accessList":null},"error":{"code":3,"data":"0xe450d38c00000000000000000000000014f9a42ed153dcd817265f57308ffd11f7fe8dba0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016345785d8a0000"}}, tx={"to":{},"data":"0xa9059cbb000000000000000000000000eb2e452fc167b5bb948c6fc2c9215ce7f4064692000000000000000000000000000000000000000000000000016345785d8a0000","from":"0x14f9a42ed153dcd817265f57308ffd11f7fe8dba","gasLimit":{},"speed":"fast"}, code=UNPREDICTABLE_GAS_LIMIT, version=@openzeppelin/defender-relay-client)
at Logger.makeError (C:\Users\-\Documents\Projects\test-relayer\node_modules\@ethersproject\logger\src.ts\index.ts:269:28)
at Logger.throwError (C:\Users\-\Documents\Projects\test-relayer\node_modules\@ethersproject\logger\src.ts\index.ts:281:20)
at C:\Users\-\Documents\Projects\test-relayer\node_modules\@openzeppelin\defender-sdk-relay-signer-client\lib\ethers\signer.js:155:31
at processTicksAndRejections (node:internal/process/task_queues:95:5)
at async Promise.all (index 3) {
reason: 'cannot estimate gas; transaction may fail or may require manual gas limit',
code: 'UNPREDICTABLE_GAS_LIMIT',
error: Error: cannot estimate gas; transaction may fail or may require manual gas limit [ See: https://links.ethers.org/v5-errors-UNPREDICTABLE_GAS_LIMIT ] (reason="execution reverted", method="estimateGas", transaction={"from":"0x14f9A42ED153dcD817265f57308FFD11f7FE8DBa","to":"0x6C83356994D60cD88116320B08B43fa198fA5D02","data":"0xa9059cbb000000000000000000000000eb2e452fc167b5bb948c6fc2c9215ce7f4064692000000000000000000000000000000000000000000000000016345785d8a0000","accessList":null}, error={"code":3,"data":"0xe450d38c00000000000000000000000014f9a42ed153dcd817265f57308ffd11f7fe8dba0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016345785d8a0000"}, code=UNPREDICTABLE_GAS_LIMIT, version=providers/5.7.2)
at Logger.makeError (C:\Users\-\Documents\Projects\test-relayer\node_modules\@ethersproject\logger\src.ts\index.ts:269:28)
at Logger.throwError (C:\Users\-\Documents\Projects\test-relayer\node_modules\@ethersproject\logger\src.ts\index.ts:281:20)
at checkError (C:\Users\-\Documents\Projects\test-relayer\node_modules\@ethersproject\providers\src.ts\json-rpc-provider.ts:78:20)
at DefenderRelayProvider.<anonymous> (C:\Users\-\Documents\Projects\test-relayer\node_modules\@ethersproject\providers\src.ts\json-rpc-provider.ts:642:20)
at step (C:\Users\-\Documents\Projects\test-relayer\node_modules\@ethersproject\providers\lib\json-rpc-provider.js:48:23)
at Object.throw (C:\Users\-\Documents\Projects\test-relayer\node_modules\@ethersproject\providers\lib\json-rpc-provider.js:29:53)
at rejected (C:\Users\-\Documents\Projects\test-relayer\node_modules\@ethersproject\providers\lib\json-rpc-provider.js:21:65)
at processTicksAndRejections (node:internal/process/task_queues:95:5) {
reason: 'execution reverted',
code: 'UNPREDICTABLE_GAS_LIMIT',
method: 'estimateGas',
transaction: {
from: '0x14f9A42ED153dcD817265f57308FFD11f7FE8DBa',
to: '0x6C83356994D60cD88116320B08B43fa198fA5D02',
data: '0xa9059cbb000000000000000000000000eb2e452fc167b5bb948c6fc2c9215ce7f4064692000000000000000000000000000000000000000000000000016345785d8a0000',
accessList: null
},
error: Error: execution reverted
at DefenderRelayProvider.send (C:\Users\-\Documents\Projects\test-relayer\node_modules\@openzeppelin\defender-sdk-relay-signer-client\lib\ethers\provider.js:58:31)
at processTicksAndRejections (node:internal/process/task_queues:95:5) {
code: 3,
data: '0xe450d38c00000000000000000000000014f9a42ed153dcd817265f57308ffd11f7fe8dba0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016345785d8a0000'
}
},
tx: {
to: Promise { '0x6C83356994D60cD88116320B08B43fa198fA5D02' },
data: '0xa9059cbb000000000000000000000000eb2e452fc167b5bb948c6fc2c9215ce7f4064692000000000000000000000000000000000000000000000000016345785d8a0000',
from: '0x14f9a42ed153dcd817265f57308ffd11f7fe8dba',
gasLimit: Promise { <rejected> [Circular *1] },
speed: 'fast'
}
}
Is there anything wrong in the code below?
Environment
openzeppelin/defender-sdk v1.10.0
ethers v6.11.1
hardhat 2.20.1
BNB chain testnet
Code to reproduce
JavaScript using ethers:
const forwarder = await ethers.deployContract("ERC2771Forwarder", [`TESTERC20ERC2771OZ forwarder`])
await forwarder.waitForDeployment()
const forwarderAddress = await forwarder.target
console.log(`forwarder has been deployed to: ${forwarderAddress}`)
const tokenContractName = `TESTERC20ERC2771OZ`
const token = await ethers.deployContract(tokenContractName, [
`Token 4622`,
`TOKEN4622`,
wallet.address,
forwarderAddress,
])
await token.waitForDeployment()
const tokenContractAddress = await token.target
console.log(`token has been deployed to: ${tokenContractAddress}`)
const { Defender } = require('@openzeppelin/defender-sdk')
const client = new Defender({ relayerApiKey: process.env.OZ_RELAYER_BSCTEST_API_KEY, relayerApiSecret: process.env.OZ_RELAYER_BSCTEST_API_SECRET })
const provider = client.relaySigner.getProvider()
const validUntil = new Date(Date.now() + 120 * 1000).toISOString()
const signer = client.relaySigner.getSigner(provider, { speed: 'fast', validUntil })
const token = await ethers.getContractAt(tokenContractName, tokenContractAddress, signer)
const destinationAddress = `0xEB2e452fC167b5bb948c6FC2c9215ce7F4064692`
const amount = ethers.parseUnits(`0.1`, `ether`)
const tx = await token.transfer(destinationAddress, amount)
Token contract in Solidity:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol";
import "@openzeppelin/contracts/metatx/ERC2771Context.sol";
contract TESTERC20ERC2771OZ is ERC20, ERC20Permit, ERC2771Context {
bytes public b;
constructor(
string memory name,
string memory symbol,
address initialHolder,
address forwarder
) ERC20(name, symbol) ERC20Permit(name) ERC2771Context(forwarder) {
_mint(initialHolder, 1000);
}
function _msgSender()
internal
view
override(Context, ERC2771Context)
returns (address)
{
return ERC2771Context._msgSender();
}
function _msgData()
internal
view
override(Context, ERC2771Context)
returns (bytes calldata)
{
return ERC2771Context._msgData();
}
function _contextSuffixLength()
internal
view
override(Context, ERC2771Context)
returns (uint256)
{
return ERC2771Context._contextSuffixLength();
}
}