diff --git a/src/abi/xtoken-backing.ts b/src/abi/xtoken-backing.ts index cf8c2f671..e3b3b879f 100644 --- a/src/abi/xtoken-backing.ts +++ b/src/abi/xtoken-backing.ts @@ -48,12 +48,6 @@ const abi = [ name: "RemoteIssuingFailure", type: "event", inputs: [ - { - name: "refundId", - type: "bytes32", - indexed: false, - internalType: "bytes32", - }, { name: "transferId", type: "bytes32", @@ -61,7 +55,7 @@ const abi = [ internalType: "bytes32", }, { - name: "mappingToken", + name: "xToken", type: "address", indexed: false, internalType: "address", @@ -97,6 +91,12 @@ const abi = [ indexed: false, internalType: "bytes32", }, + { + name: "nonce", + type: "uint256", + indexed: false, + internalType: "uint256", + }, { name: "remoteChainId", type: "uint256", @@ -249,6 +249,45 @@ const abi = [ ], stateMutability: "view", }, + { + name: "TRANSFER_DELIVERED", + type: "function", + inputs: [], + outputs: [ + { + name: "", + type: "uint256", + internalType: "uint256", + }, + ], + stateMutability: "view", + }, + { + name: "TRANSFER_REFUNDED", + type: "function", + inputs: [], + outputs: [ + { + name: "", + type: "uint256", + internalType: "uint256", + }, + ], + stateMutability: "view", + }, + { + name: "TRANSFER_UNFILLED", + type: "function", + inputs: [], + outputs: [ + { + name: "", + type: "uint256", + internalType: "uint256", + }, + ], + stateMutability: "view", + }, { name: "_slotReserved", type: "function", @@ -335,6 +374,11 @@ const abi = [ type: "address", internalType: "address", }, + { + name: "_originalSender", + type: "address", + internalType: "address", + }, { name: "_recipient", type: "address", @@ -345,6 +389,11 @@ const abi = [ type: "uint256", internalType: "uint256", }, + { + name: "_nonce", + type: "uint256", + internalType: "uint256", + }, ], outputs: [ { @@ -360,10 +409,78 @@ const abi = [ type: "function", inputs: [ { - name: "_transferId", + name: "_originalToken", + type: "address", + internalType: "address", + }, + { + name: "_originalSender", + type: "address", + internalType: "address", + }, + { + name: "_recipient", + type: "address", + internalType: "address", + }, + { + name: "_amount", + type: "uint256", + internalType: "uint256", + }, + { + name: "_nonce", + type: "uint256", + internalType: "uint256", + }, + ], + outputs: [ + { + name: "", + type: "bytes", + internalType: "bytes", + }, + ], + stateMutability: "view", + }, + { + name: "filledTransfers", + type: "function", + inputs: [ + { + name: "", type: "bytes32", internalType: "bytes32", }, + ], + outputs: [ + { + name: "", + type: "uint256", + internalType: "uint256", + }, + ], + stateMutability: "view", + }, + { + name: "getTransferId", + type: "function", + inputs: [ + { + name: "_nonce", + type: "uint256", + internalType: "uint256", + }, + { + name: "_sourceChainId", + type: "uint256", + internalType: "uint256", + }, + { + name: "_targetChainId", + type: "uint256", + internalType: "uint256", + }, { name: "_originalToken", type: "address", @@ -374,6 +491,11 @@ const abi = [ type: "address", internalType: "address", }, + { + name: "_recipient", + type: "address", + internalType: "address", + }, { name: "_amount", type: "uint256", @@ -383,11 +505,11 @@ const abi = [ outputs: [ { name: "", - type: "bytes", - internalType: "bytes", + type: "bytes32", + internalType: "bytes32", }, ], - stateMutability: "view", + stateMutability: "pure", }, { name: "guard", @@ -412,17 +534,17 @@ const abi = [ internalType: "uint256", }, { - name: "_transferId", - type: "bytes32", - internalType: "bytes32", + name: "_originalToken", + type: "address", + internalType: "address", }, { - name: "_originalToken", + name: "_originalSender", type: "address", internalType: "address", }, { - name: "_originSender", + name: "_recipient", type: "address", internalType: "address", }, @@ -431,6 +553,11 @@ const abi = [ type: "uint256", internalType: "uint256", }, + { + name: "_nonce", + type: "uint256", + internalType: "uint256", + }, ], outputs: [], stateMutability: "nonpayable", @@ -477,6 +604,11 @@ const abi = [ type: "uint256", internalType: "uint256", }, + { + name: "_nonce", + type: "uint256", + internalType: "uint256", + }, { name: "_extParams", type: "bytes", @@ -486,30 +618,6 @@ const abi = [ outputs: [], stateMutability: "payable", }, - { - name: "lockedMessages", - type: "function", - inputs: [ - { - name: "", - type: "bytes32", - internalType: "bytes32", - }, - ], - outputs: [ - { - name: "hash", - type: "bytes32", - internalType: "bytes32", - }, - { - name: "hasRefundForFailed", - type: "bool", - internalType: "bool", - }, - ], - stateMutability: "view", - }, { name: "messagers", type: "function", @@ -654,14 +762,33 @@ const abi = [ stateMutability: "nonpayable", }, { - name: "requestRemoteIssuingForUnlockFailure", + name: "requestInfos", type: "function", inputs: [ { - name: "_transferId", + name: "", type: "bytes32", internalType: "bytes32", }, + ], + outputs: [ + { + name: "isRequested", + type: "bool", + internalType: "bool", + }, + { + name: "hasRefundForFailed", + type: "bool", + internalType: "bool", + }, + ], + stateMutability: "view", + }, + { + name: "requestRemoteIssuingForUnlockFailure", + type: "function", + inputs: [ { name: "_remoteChainId", type: "uint256", @@ -677,11 +804,21 @@ const abi = [ type: "address", internalType: "address", }, + { + name: "_recipient", + type: "address", + internalType: "address", + }, { name: "_amount", type: "uint256", internalType: "uint256", }, + { + name: "_nonce", + type: "uint256", + internalType: "uint256", + }, { name: "_extParams", type: "bytes", @@ -840,6 +977,11 @@ const abi = [ type: "address", internalType: "address", }, + { + name: "_originSender", + type: "address", + internalType: "address", + }, { name: "_recipient", type: "address", @@ -850,28 +992,14 @@ const abi = [ type: "uint256", internalType: "uint256", }, - ], - outputs: [], - stateMutability: "nonpayable", - }, - { - name: "unlockedTransferIds", - type: "function", - inputs: [ { - name: "", - type: "bytes32", - internalType: "bytes32", - }, - ], - outputs: [ - { - name: "", - type: "bool", - internalType: "bool", + name: "_nonce", + type: "uint256", + internalType: "uint256", }, ], - stateMutability: "view", + outputs: [], + stateMutability: "nonpayable", }, { name: "unpause", diff --git a/src/abi/xtoken-issuing.ts b/src/abi/xtoken-issuing.ts index b4d6e1a9f..337546137 100644 --- a/src/abi/xtoken-issuing.ts +++ b/src/abi/xtoken-issuing.ts @@ -3,11 +3,11 @@ const abi = [ anonymous: false, inputs: [ { indexed: false, internalType: "bytes32", name: "transferId", type: "bytes32" }, + { indexed: false, internalType: "uint256", name: "nonce", type: "uint256" }, { indexed: false, internalType: "uint256", name: "remoteChainId", type: "uint256" }, { indexed: false, internalType: "address", name: "sender", type: "address" }, { indexed: false, internalType: "address", name: "recipient", type: "address" }, { indexed: false, internalType: "address", name: "originalToken", type: "address" }, - { indexed: false, internalType: "address", name: "xToken", type: "address" }, { indexed: false, internalType: "uint256", name: "amount", type: "uint256" }, { indexed: false, internalType: "uint256", name: "fee", type: "uint256" }, ], @@ -59,7 +59,6 @@ const abi = [ { anonymous: false, inputs: [ - { indexed: false, internalType: "bytes32", name: "refundId", type: "bytes32" }, { indexed: false, internalType: "bytes32", name: "transferId", type: "bytes32" }, { indexed: false, internalType: "address", name: "originalToken", type: "address" }, { indexed: false, internalType: "address", name: "originalSender", type: "address" }, @@ -115,6 +114,27 @@ const abi = [ stateMutability: "view", type: "function", }, + { + inputs: [], + name: "TRANSFER_DELIVERED", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "TRANSFER_REFUNDED", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "TRANSFER_UNFILLED", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function", + }, { inputs: [{ internalType: "address", name: "", type: "address" }], name: "_slotReserved", @@ -123,11 +143,19 @@ const abi = [ type: "function", }, { inputs: [], name: "acceptOwnership", outputs: [], stateMutability: "nonpayable", type: "function" }, + { + inputs: [{ internalType: "address", name: "_xToken", type: "address" }], + name: "acceptxTokenOwnership", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, { inputs: [ { internalType: "address", name: "_xToken", type: "address" }, { internalType: "address", name: "_recipient", type: "address" }, { internalType: "uint256", name: "_amount", type: "uint256" }, + { internalType: "uint256", name: "_nonce", type: "uint256" }, { internalType: "bytes", name: "_extParams", type: "bytes" }, ], name: "burnAndRemoteUnlock", @@ -135,16 +163,6 @@ const abi = [ stateMutability: "payable", type: "function", }, - { - inputs: [{ internalType: "bytes32", name: "", type: "bytes32" }], - name: "burnMessages", - outputs: [ - { internalType: "bytes32", name: "hash", type: "bytes32" }, - { internalType: "bool", name: "hasRefundForFailed", type: "bool" }, - ], - stateMutability: "view", - type: "function", - }, { inputs: [{ internalType: "address", name: "token", type: "address" }], name: "calcMaxWithdraw", @@ -168,10 +186,11 @@ const abi = [ }, { inputs: [ - { internalType: "bytes32", name: "_transferId", type: "bytes32" }, { internalType: "address", name: "_originalToken", type: "address" }, { internalType: "address", name: "_originalSender", type: "address" }, + { internalType: "address", name: "_recipient", type: "address" }, { internalType: "uint256", name: "_amount", type: "uint256" }, + { internalType: "uint256", name: "_nonce", type: "uint256" }, ], name: "encodeUnlockForIssuingFailureFromRemote", outputs: [{ internalType: "bytes", name: "", type: "bytes" }], @@ -181,14 +200,38 @@ const abi = [ { inputs: [ { internalType: "address", name: "_originalToken", type: "address" }, + { internalType: "address", name: "_originalSender", type: "address" }, { internalType: "address", name: "_recipient", type: "address" }, { internalType: "uint256", name: "_amount", type: "uint256" }, + { internalType: "uint256", name: "_nonce", type: "uint256" }, ], name: "encodeUnlockFromRemote", outputs: [{ internalType: "bytes", name: "", type: "bytes" }], stateMutability: "view", type: "function", }, + { + inputs: [{ internalType: "bytes32", name: "", type: "bytes32" }], + name: "filledTransfers", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "uint256", name: "_nonce", type: "uint256" }, + { internalType: "uint256", name: "_sourceChainId", type: "uint256" }, + { internalType: "uint256", name: "_targetChainId", type: "uint256" }, + { internalType: "address", name: "_originalToken", type: "address" }, + { internalType: "address", name: "_originalSender", type: "address" }, + { internalType: "address", name: "_recipient", type: "address" }, + { internalType: "uint256", name: "_amount", type: "uint256" }, + ], + name: "getTransferId", + outputs: [{ internalType: "bytes32", name: "", type: "bytes32" }], + stateMutability: "pure", + type: "function", + }, { inputs: [], name: "guard", @@ -199,10 +242,11 @@ const abi = [ { inputs: [ { internalType: "uint256", name: "_originalChainId", type: "uint256" }, - { internalType: "bytes32", name: "_transferId", type: "bytes32" }, { internalType: "address", name: "_originalToken", type: "address" }, { internalType: "address", name: "_originalSender", type: "address" }, + { internalType: "address", name: "_recipient", type: "address" }, { internalType: "uint256", name: "_amount", type: "uint256" }, + { internalType: "uint256", name: "_nonce", type: "uint256" }, ], name: "handleIssuingForUnlockFailureFromRemote", outputs: [], @@ -219,19 +263,14 @@ const abi = [ stateMutability: "nonpayable", type: "function", }, - { - inputs: [{ internalType: "bytes32", name: "", type: "bytes32" }], - name: "issueTransferIds", - outputs: [{ internalType: "bool", name: "", type: "bool" }], - stateMutability: "view", - type: "function", - }, { inputs: [ { internalType: "uint256", name: "_remoteChainId", type: "uint256" }, { internalType: "address", name: "_originalToken", type: "address" }, + { internalType: "address", name: "_originalSender", type: "address" }, { internalType: "address", name: "_recipient", type: "address" }, { internalType: "uint256", name: "_amount", type: "uint256" }, + { internalType: "uint256", name: "_nonce", type: "uint256" }, ], name: "issuexToken", outputs: [], @@ -309,13 +348,24 @@ const abi = [ stateMutability: "nonpayable", type: "function", }, + { + inputs: [{ internalType: "bytes32", name: "", type: "bytes32" }], + name: "requestInfos", + outputs: [ + { internalType: "bool", name: "isRequested", type: "bool" }, + { internalType: "bool", name: "hasRefundForFailed", type: "bool" }, + ], + stateMutability: "view", + type: "function", + }, { inputs: [ - { internalType: "bytes32", name: "_transferId", type: "bytes32" }, { internalType: "uint256", name: "_originalChainId", type: "uint256" }, { internalType: "address", name: "_originalToken", type: "address" }, { internalType: "address", name: "_originalSender", type: "address" }, + { internalType: "address", name: "_recipient", type: "address" }, { internalType: "uint256", name: "_amount", type: "uint256" }, + { internalType: "uint256", name: "_nonce", type: "uint256" }, { internalType: "bytes", name: "_extParams", type: "bytes" }, ], name: "requestRemoteUnlockForIssuingFailure", @@ -383,6 +433,16 @@ const abi = [ stateMutability: "nonpayable", type: "function", }, + { + inputs: [ + { internalType: "address", name: "_xToken", type: "address" }, + { internalType: "address", name: "_newOwner", type: "address" }, + ], + name: "transferxTokenOwnership", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, { inputs: [], name: "unpause", outputs: [], stateMutability: "nonpayable", type: "function" }, { inputs: [{ internalType: "address", name: "_guard", type: "address" }], diff --git a/src/bridges/xtoken-v3.ts b/src/bridges/xtoken-v3.ts index 201d16d7d..c5acebc7f 100644 --- a/src/bridges/xtoken-v3.ts +++ b/src/bridges/xtoken-v3.ts @@ -17,8 +17,8 @@ export class XTokenV3Bridge extends BaseBridge { } private initContract() { - const backing = "0xb137BDf1Ad5392027832f54a4409685Ef52Aa9dA"; - const issuing = "0x44A001aF6AcD2d5f5cB82FCB14Af3d497D56faB4"; + const backing = "0xbdC7bbF408931C5d666b4F0520E0D9E9A0B04e99"; + const issuing = "0xf22D0bb66b39745Ae6e3fEa3E5859d7f0b367Fd1"; this.initContractByBackingIssuing(backing, issuing); } @@ -28,7 +28,8 @@ export class XTokenV3Bridge extends BaseBridge { amount: bigint, options?: TransferOptions & { askEstimateGas?: boolean }, ): Promise { - const feeAndParams = await this._getMsglineFeeAndParams(sender, recipient, amount); + const nonce = BigInt(Date.now()); + const feeAndParams = await this._getMsglineFeeAndParams(sender, recipient, amount, nonce); const account = await this.getSigner(); if ( @@ -47,7 +48,14 @@ export class XTokenV3Bridge extends BaseBridge { address: this.contract.sourceAddress, abi: (await import("@/abi/xtoken-backing")).default, functionName: "lockAndRemoteIssuing", - args: [BigInt(this.targetChain.id), this.sourceToken.address, recipient, amount, feeAndParams.extParams], + args: [ + BigInt(this.targetChain.id), + this.sourceToken.address, + recipient, + amount, + nonce, + feeAndParams.extParams, + ], value: this.sourceToken.type === "native" ? amount + feeAndParams.fee : feeAndParams.fee, gas: this.getTxGasLimit(), account, @@ -64,7 +72,7 @@ export class XTokenV3Bridge extends BaseBridge { address: this.contract.sourceAddress, abi: (await import("@/abi/xtoken-issuing")).default, functionName: "burnAndRemoteUnlock", - args: [this.sourceToken.address, recipient, amount, feeAndParams.extParams], + args: [this.sourceToken.address, recipient, amount, nonce, feeAndParams.extParams], value: this.sourceToken.type === "native" ? amount + feeAndParams.fee : feeAndParams.fee, gas: this.getTxGasLimit(), account, @@ -81,7 +89,7 @@ export class XTokenV3Bridge extends BaseBridge { return; } - private async _getMsglineFeeAndParams(sender: Address, recipient: Address, amount: bigint) { + private async _getMsglineFeeAndParams(sender: Address, recipient: Address, amount: bigint, nonce: bigint) { const sourceMessager = this.sourceChain?.messager?.msgline; const targetMessager = this.targetChain?.messager?.msgline; @@ -98,12 +106,12 @@ export class XTokenV3Bridge extends BaseBridge { ? encodeFunctionData({ abi: (await import("@/abi/xtoken-issuing")).default, functionName: "issuexToken", - args: [BigInt(this.sourceChain.id), this.sourceToken.address, recipient, amount], + args: [BigInt(this.sourceChain.id), this.sourceToken.address, sender, recipient, amount, nonce], }) : encodeFunctionData({ abi: (await import("@/abi/xtoken-backing")).default, functionName: "unlockFromRemote", - args: [BigInt(this.sourceChain.id), this.targetToken.address, recipient, amount], + args: [BigInt(this.sourceChain.id), this.targetToken.address, sender, recipient, amount, nonce], }); const payload = encodeFunctionData({ @@ -125,9 +133,10 @@ export class XTokenV3Bridge extends BaseBridge { async getFee(args?: GetFeeArgs | undefined): Promise<{ value: bigint; token: Token } | undefined> { if (this.sourceNativeToken) { + const nonce = BigInt(Date.now()); const sender = args?.sender ?? "0x0000000000000000000000000000000000000000"; const recipient = args?.recipient ?? "0x0000000000000000000000000000000000000000"; - const feeAndParams = await this._getMsglineFeeAndParams(sender, recipient, args?.transferAmount ?? 0n); + const feeAndParams = await this._getMsglineFeeAndParams(sender, recipient, args?.transferAmount ?? 0n, nonce); if (feeAndParams) { return { value: feeAndParams.fee, token: this.sourceNativeToken }; }