11import _ from "lodash" ;
22import { providers } from "ethers" ;
3- import { DepositWithBlock , Fill , FillWithBlock } from "../../../interfaces" ;
3+ import { Deposit , DepositWithBlock , Fill , FillWithBlock } from "../../../interfaces" ;
44import { getBlockRangeForChain , isSlowFill , chainIsEvm , isValidEvmAddress , isDefined } from "../../../utils" ;
55import { HubPoolClient } from "../../HubPoolClient" ;
66
@@ -47,34 +47,51 @@ export function getRefundInformationFromFill(
4747 } ;
4848}
4949
50+ export function getRepaymentChainId ( fill : Fill , matchedDeposit : Deposit ) : number {
51+ // Lite chain deposits force repayment on origin chain.
52+ return matchedDeposit . fromLiteChain ? fill . originChainId : fill . repaymentChainId ;
53+ }
54+
55+ export function isEvmRepaymentValid (
56+ fill : Fill ,
57+ repaymentChainId : number ,
58+ possibleRepaymentChainIds : number [ ] = [ ]
59+ ) : boolean {
60+ // Slow fills don't result in repayments so they're always valid.
61+ if ( isSlowFill ( fill ) ) {
62+ return true ;
63+ }
64+ // Return undefined if the requested repayment chain ID is not in a passed in set of eligible chains. This can
65+ // be used by the caller to narrow the chains to those that are not disabled in the config store.
66+ if ( possibleRepaymentChainIds . length > 0 && ! possibleRepaymentChainIds . includes ( repaymentChainId ) ) {
67+ return false ;
68+ }
69+ return chainIsEvm ( repaymentChainId ) && isValidEvmAddress ( fill . relayer ) ;
70+ }
71+
5072// Verify that a fill sent to an EVM chain has a 20 byte address. If the fill does not, then attempt
5173// to repay the `msg.sender` of the relay transaction. Otherwise, return undefined.
5274export async function verifyFillRepayment (
53- fill : FillWithBlock ,
75+ _fill : FillWithBlock ,
5476 destinationChainProvider : providers . Provider ,
5577 matchedDeposit : DepositWithBlock ,
56- possibleRepaymentChainIds : number [ ]
78+ possibleRepaymentChainIds : number [ ] = [ ]
5779) : Promise < FillWithBlock | undefined > {
58- // Slow fills don't result in repayments so they're always valid.
59- if ( isSlowFill ( fill ) ) {
60- return fill ;
61- }
62- // Lite chain deposits force repayment on origin chain.
63- const repaymentChainId = matchedDeposit . fromLiteChain ? fill . originChainId : fill . repaymentChainId ;
64- // Return undefined if the requested repayment chain ID is not recognized by the hub pool.
65- if ( ! possibleRepaymentChainIds . includes ( repaymentChainId ) ) {
66- return undefined ;
67- }
68- const updatedFill = _ . cloneDeep ( fill ) ;
80+ const fill = _ . cloneDeep ( _fill ) ;
6981
70- // If the fill requests repayment on a chain where the repayment address is not valid, attempt to find a valid
71- // repayment address, otherwise return undefined.
82+ const repaymentChainId = getRepaymentChainId ( fill , matchedDeposit ) ;
83+ const validEvmRepayment = isEvmRepaymentValid ( fill , repaymentChainId , possibleRepaymentChainIds ) ;
7284
73- // Case 1: repayment chain is an EVM chain but repayment address is not a valid EVM address.
74- if ( chainIsEvm ( repaymentChainId ) && ! isValidEvmAddress ( updatedFill . relayer ) ) {
85+ // Case 1: Repayment chain is EVM and repayment address is valid EVM address.
86+ if ( validEvmRepayment ) {
87+ return fill ;
88+ }
89+ // Case 2: Repayment chain is EVM but repayment address is not a valid EVM address. Attempt to switch repayment
90+ // address to msg.sender of relay transaction.
91+ else if ( chainIsEvm ( repaymentChainId ) && ! isValidEvmAddress ( fill . relayer ) ) {
7592 // TODO: Handle case where fill was sent on non-EVM chain, in which case the following call would fail
7693 // or return something unexpected. We'd want to return undefined here.
77- const fillTransaction = await destinationChainProvider . getTransaction ( updatedFill . transactionHash ) ;
94+ const fillTransaction = await destinationChainProvider . getTransaction ( fill . transactionHash ) ;
7895 const destinationRelayer = fillTransaction ?. from ;
7996 // Repayment chain is still an EVM chain, but the msg.sender is a bytes32 address, so the fill is invalid.
8097 if ( ! isDefined ( destinationRelayer ) || ! isValidEvmAddress ( destinationRelayer ) ) {
@@ -83,9 +100,11 @@ export async function verifyFillRepayment(
83100 // Otherwise, assume the relayer to be repaid is the msg.sender. We don't need to modify the repayment chain since
84101 // the getTransaction() call would only succeed if the fill was sent on an EVM chain and therefore the msg.sender
85102 // is a valid EVM address and the repayment chain is an EVM chain.
86- updatedFill . relayer = destinationRelayer ;
103+ fill . relayer = destinationRelayer ;
104+ return fill ;
105+ }
106+ // Case 3: Repayment chain is not an EVM chain, must be invalid.
107+ else {
108+ return undefined ;
87109 }
88-
89- // Case 2: TODO repayment chain is an SVM chain and repayment address is not a valid SVM address.
90- return updatedFill ;
91110}
0 commit comments