Skip to content

Commit

Permalink
fix(OptimismAdapter): Support custom SNX Adapter ABI (#876)
Browse files Browse the repository at this point in the history
* fix(OptimismAdapter): Support custom SNX Adapter ABI

We previously burned SNX by sending to the wrong bridge. See [here](#874 (comment)) for example.

* Update OptimismAdapter.ts
  • Loading branch information
nicholaspai committed Aug 11, 2023
1 parent 3de58d6 commit 52552a7
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 30 deletions.
37 changes: 25 additions & 12 deletions src/clients/bridges/OptimismAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ export class OptimismAdapter extends BaseAdapter {
private txnClient: TransactionClient;

private customL1OptimismBridgeAddresses = {
[TOKEN_SYMBOLS_MAP.DAI.addresses[1]]: CONTRACT_ADDRESSES[1].daiOptimismBridge.address,
[TOKEN_SYMBOLS_MAP.DAI.addresses[1]]: CONTRACT_ADDRESSES[1].daiOptimismBridge,
[TOKEN_SYMBOLS_MAP.SNX.addresses[1]]: CONTRACT_ADDRESSES[1].snxOptimismBridge,
} as const;

private customOvmBridgeAddresses = {
[TOKEN_SYMBOLS_MAP.DAI.addresses[1]]: CONTRACT_ADDRESSES[10].daiOptimismBridge.address,
[TOKEN_SYMBOLS_MAP.DAI.addresses[1]]: CONTRACT_ADDRESSES[10].daiOptimismBridge,
[TOKEN_SYMBOLS_MAP.SNX.addresses[1]]: CONTRACT_ADDRESSES[10].snxOptimismBridge,
} as const;

private atomicDepositorAddress = CONTRACT_ADDRESSES[1].atomicDepositor.address;
Expand All @@ -44,18 +46,25 @@ export class OptimismAdapter extends BaseAdapter {
// Fetch bridge events for all monitored addresses.
for (const monitoredAddress of this.monitoredAddresses) {
for (const l1Token of l1Tokens) {
const l1Method = this.isWeth(l1Token) ? "ETHDepositInitiated" : "ERC20DepositInitiated";
const l1Method = this.isWeth(l1Token)
? "ETHDepositInitiated"
: this.isSNX(l1Token)
? "DepositInitiated"
: "ERC20DepositInitiated";
let l1SearchFilter = [l1Token, undefined, monitoredAddress];
let l2SearchFilter = [l1Token, undefined, monitoredAddress];
if (this.isWeth(l1Token)) {
l1SearchFilter = [undefined, monitoredAddress];
l2SearchFilter = [ZERO_ADDRESS, undefined, monitoredAddress];
} else if (this.isSNX(l1Token)) {
l1SearchFilter = [monitoredAddress];
l2SearchFilter = [monitoredAddress];
}
const l1Bridge = this.getL1Bridge(l1Token);
const l2Bridge = this.getL2Bridge(l1Token);
// Transfers might have come from the monitored address itself or another sender address (if specified).
const senderAddress = this.senderAddress || this.atomicDepositorAddress;
const adapterSearchConfig = [ZERO_ADDRESS, undefined, senderAddress];
const adapterSearchConfig = this.isSNX(l1Token) ? [senderAddress] : [ZERO_ADDRESS, undefined, senderAddress];
promises.push(
paginatedEventQuery(l1Bridge, l1Bridge.filters[l1Method](...l1SearchFilter), l1SearchConfig),
paginatedEventQuery(l2Bridge, l2Bridge.filters.DepositFinalized(...l2SearchFilter), l2SearchConfig),
Expand Down Expand Up @@ -124,8 +133,8 @@ export class OptimismAdapter extends BaseAdapter {
const originChainId = (await contract.provider.getNetwork()).chainId;
assert(originChainId !== destinationChainId);

let method = "depositERC20";
let args = [l1Token, l2Token, amount, l2Gas, "0x"];
let method = this.isSNX(l1Token) ? "depositTo" : "depositERC20";
let args = this.isSNX(l1Token) ? [address, amount] : [l1Token, l2Token, amount, l2Gas, "0x"];

// If this token is WETH(the tokenToEvent maps to the ETH method) then we modify the params to call bridgeWethToOvm
// on the atomic depositor contract. Note that value is still 0 as this method will pull WETH from the caller.
Expand Down Expand Up @@ -175,10 +184,10 @@ export class OptimismAdapter extends BaseAdapter {
if (this.chainId !== 10) {
throw new Error(`chainId ${this.chainId} is not supported`);
}
const l1BridgeAddress = this.hasCustomL1Bridge(l1Token)
const l1BridgeData = this.hasCustomL1Bridge(l1Token)
? this.customL1OptimismBridgeAddresses[l1Token]
: CONTRACT_ADDRESSES[1].ovmStandardBridge.address;
return new Contract(l1BridgeAddress, CONTRACT_ADDRESSES[1].daiOptimismBridge.abi, this.getSigner(1));
: CONTRACT_ADDRESSES[1].ovmStandardBridge;
return new Contract(l1BridgeData.address, l1BridgeData.abi, this.getSigner(1));
}

getL1TokenGateway(l1Token: string): Contract {
Expand All @@ -193,10 +202,14 @@ export class OptimismAdapter extends BaseAdapter {
if (this.chainId !== 10) {
throw new Error(`chainId ${this.chainId} is not supported`);
}
const l2BridgeAddress = this.hasCustomL2Bridge(l1Token)
const l2BridgeData = this.hasCustomL2Bridge(l1Token)
? this.customOvmBridgeAddresses[l1Token]
: CONTRACT_ADDRESSES[10].ovmStandardBridge.address;
return new Contract(l2BridgeAddress, CONTRACT_ADDRESSES[10].ovmStandardBridge.abi, this.getSigner(this.chainId));
: CONTRACT_ADDRESSES[10].ovmStandardBridge;
return new Contract(l2BridgeData.address, l2BridgeData.abi, this.getSigner(this.chainId));
}

isSNX(l1Token: string): boolean {
return l1Token.toLowerCase() === "0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f";
}

private hasCustomL1Bridge(l1Token: string): boolean {
Expand Down
54 changes: 36 additions & 18 deletions src/common/ContractAddresses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,36 +73,40 @@ export const CONTRACT_ADDRESSES: {
name: "ERC20DepositInitiated",
type: "event",
},
{
inputs: [
{ internalType: "address", name: "_l1Token", type: "address" },
{ internalType: "address", name: "_l2Token", type: "address" },
{ internalType: "uint256", name: "_amount", type: "uint256" },
{ internalType: "uint32", name: "_l2Gas", type: "uint32" },
{ internalType: "bytes", name: "_data", type: "bytes" },
],
name: "depositERC20",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
],
},
snxOptimismBridge: {
address: "0x39Ea01a0298C315d149a490E34B59Dbf2EC7e48F",
abi: [
{
anonymous: false,
inputs: [
{ indexed: true, internalType: "address", name: "_from", type: "address" },
{ indexed: true, internalType: "address", name: "_to", type: "address" },
{ indexed: false, internalType: "uint256", name: "_amount", type: "uint256" },
{ indexed: false, internalType: "bytes", name: "_data", type: "bytes" },
],
name: "ETHDepositInitiated",
name: "DepositInitiated",
type: "event",
},
{
inputs: [
{ internalType: "uint32", name: "_l2Gas", type: "uint32" },
{ internalType: "bytes", name: "_data", type: "bytes" },
],
name: "depositETH",
outputs: [],
stateMutability: "payable",
type: "function",
},
{
inputs: [
{ internalType: "address", name: "_l1Token", type: "address" },
{ internalType: "address", name: "_l2Token", type: "address" },
{ internalType: "uint256", name: "_amount", type: "uint256" },
{ internalType: "uint32", name: "_l2Gas", type: "uint32" },
{ internalType: "bytes", name: "_data", type: "bytes" },
{ internalType: "address", name: "to", type: "address" },
{ internalType: "uint256", name: "amount", type: "uint256" },
],
name: "depositERC20",
name: "depositTo",
outputs: [],
stateMutability: "nonpayable",
type: "function",
Expand Down Expand Up @@ -333,6 +337,20 @@ export const CONTRACT_ADDRESSES: {
},
],
},
snxOptimismBridge: {
address: "0x136b1EC699c62b0606854056f02dC7Bb80482d63",
abi: [
{
anonymous: false,
inputs: [
{ indexed: true, internalType: "address", name: "_to", type: "address" },
{ indexed: false, internalType: "uint256", name: "_amount", type: "uint256" },
],
name: "DepositFinalized",
type: "event",
},
],
},
ovmStandardBridge: {
address: "0x4200000000000000000000000000000000000010",
abi: [
Expand Down

0 comments on commit 52552a7

Please sign in to comment.