1
1
import _ from "lodash" ;
2
2
import { providers } from "ethers" ;
3
- import { DepositWithBlock , Fill , FillWithBlock } from "../../../interfaces" ;
3
+ import { Deposit , DepositWithBlock , Fill , FillWithBlock } from "../../../interfaces" ;
4
4
import { getBlockRangeForChain , isSlowFill , chainIsEvm , isValidEvmAddress , isDefined } from "../../../utils" ;
5
5
import { HubPoolClient } from "../../HubPoolClient" ;
6
6
@@ -47,34 +47,51 @@ export function getRefundInformationFromFill(
47
47
} ;
48
48
}
49
49
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
+
50
72
// Verify that a fill sent to an EVM chain has a 20 byte address. If the fill does not, then attempt
51
73
// to repay the `msg.sender` of the relay transaction. Otherwise, return undefined.
52
74
export async function verifyFillRepayment (
53
- fill : FillWithBlock ,
75
+ _fill : FillWithBlock ,
54
76
destinationChainProvider : providers . Provider ,
55
77
matchedDeposit : DepositWithBlock ,
56
- possibleRepaymentChainIds : number [ ]
78
+ possibleRepaymentChainIds : number [ ] = [ ]
57
79
) : 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 ) ;
69
81
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 ) ;
72
84
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 ) ) {
75
92
// TODO: Handle case where fill was sent on non-EVM chain, in which case the following call would fail
76
93
// 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 ) ;
78
95
const destinationRelayer = fillTransaction ?. from ;
79
96
// Repayment chain is still an EVM chain, but the msg.sender is a bytes32 address, so the fill is invalid.
80
97
if ( ! isDefined ( destinationRelayer ) || ! isValidEvmAddress ( destinationRelayer ) ) {
@@ -83,9 +100,11 @@ export async function verifyFillRepayment(
83
100
// Otherwise, assume the relayer to be repaid is the msg.sender. We don't need to modify the repayment chain since
84
101
// the getTransaction() call would only succeed if the fill was sent on an EVM chain and therefore the msg.sender
85
102
// 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 ;
87
109
}
88
-
89
- // Case 2: TODO repayment chain is an SVM chain and repayment address is not a valid SVM address.
90
- return updatedFill ;
91
110
}
0 commit comments