@@ -8,18 +8,27 @@ import { chainIds, chainIdsToName } from "../../config/index.js";
88import { Erc20__factory } from "../../typechain/factories/contracts/Erc20__factory.js" ;
99import { EcoAdapter__factory } from "../../typechain/factories/eco/contracts/EcoAdapter__factory.js" ;
1010import { BaseFiller } from "../BaseFiller.js" ;
11- import { retrieveOriginInfo , retrieveTargetInfo } from "../utils.js" ;
11+ import {
12+ retrieveOriginInfo ,
13+ retrieveTargetInfo ,
14+ retrieveTokenBalance ,
15+ } from "../utils.js" ;
1216import { allowBlockLists , metadata } from "./config/index.js" ;
1317import type { EcoMetadata , IntentData , ParsedArgs } from "./types.js" ;
1418import { log , withdrawRewards } from "./utils.js" ;
1519
16- type Metadata = {
20+ export type Metadata = {
1721 adapters : { [ chainId : string ] : EcoMetadata [ "adapters" ] [ number ] } ;
1822 protocolName : EcoMetadata [ "protocolName" ] ;
1923} ;
2024
25+ export type EcoRule = EcoFiller [ "rules" ] [ number ] ;
26+
2127export class EcoFiller extends BaseFiller < Metadata , ParsedArgs , IntentData > {
22- constructor ( multiProvider : MultiProvider ) {
28+ constructor (
29+ multiProvider : MultiProvider ,
30+ rules ?: BaseFiller < Metadata , ParsedArgs , IntentData > [ "rules" ] ,
31+ ) {
2332 const { adapters, protocolName } = metadata ;
2433 const ecoFillerMetadata = {
2534 adapters : adapters . reduce < {
@@ -34,7 +43,7 @@ export class EcoFiller extends BaseFiller<Metadata, ParsedArgs, IntentData> {
3443 protocolName,
3544 } ;
3645
37- super ( multiProvider , allowBlockLists , ecoFillerMetadata , log ) ;
46+ super ( multiProvider , allowBlockLists , ecoFillerMetadata , log , rules ) ;
3847 }
3948
4049 protected retrieveOriginInfo ( parsedArgs : ParsedArgs , chainName : string ) {
@@ -82,62 +91,8 @@ export class EcoFiller extends BaseFiller<Metadata, ParsedArgs, IntentData> {
8291 } ;
8392 }
8493
85- await super . prepareIntent ( parsedArgs ) ;
86-
8794 try {
88- const erc20Interface = Erc20__factory . createInterface ( ) ;
89-
90- const requiredAmountsByTarget = parsedArgs . _targets . reduce < {
91- [ tokenAddress : string ] : BigNumber ;
92- } > ( ( acc , target , index ) => {
93- const [ , amount ] = erc20Interface . decodeFunctionData (
94- "transfer" ,
95- parsedArgs . _data [ index ] ,
96- ) as [ unknown , BigNumber ] ;
97-
98- acc [ target ] ||= Zero ;
99- acc [ target ] = acc [ target ] . add ( amount ) ;
100-
101- return acc ;
102- } , { } ) ;
103-
104- const fillerAddress = await this . multiProvider . getSignerAddress (
105- adapter . chainName ,
106- ) ;
107- const signer = this . multiProvider . getSigner ( adapter . chainName ) ;
108-
109- const areTargetFundsAvailable = await Promise . all (
110- Object . entries ( requiredAmountsByTarget ) . map (
111- async ( [ target , requiredAmount ] ) => {
112- const erc20 = Erc20__factory . connect ( target , signer ) ;
113-
114- const balance = await erc20 . balanceOf ( fillerAddress ) ;
115- return balance . gte ( requiredAmount ) ;
116- } ,
117- ) ,
118- ) ;
119-
120- if ( ! areTargetFundsAvailable . every ( Boolean ) ) {
121- return { error : "Not enough tokens" , success : false } ;
122- }
123-
124- this . log . debug ( {
125- msg : "Approving tokens" ,
126- protocolName : this . metadata . protocolName ,
127- intentHash : parsedArgs . _hash ,
128- adapterAddress : adapter . address ,
129- } ) ;
130-
131- await Promise . all (
132- Object . entries ( requiredAmountsByTarget ) . map (
133- async ( [ target , requiredAmount ] ) => {
134- const erc20 = Erc20__factory . connect ( target , signer ) ;
135-
136- const tx = await erc20 . approve ( adapter . address , requiredAmount ) ;
137- await tx . wait ( ) ;
138- } ,
139- ) ,
140- ) ;
95+ await super . prepareIntent ( parsedArgs ) ;
14196
14297 return { data : { adapter } , success : true } ;
14398 } catch ( error : any ) {
@@ -158,6 +113,41 @@ export class EcoFiller extends BaseFiller<Metadata, ParsedArgs, IntentData> {
158113 intent : `${ this . metadata . protocolName } -${ parsedArgs . _hash } ` ,
159114 } ) ;
160115
116+ this . log . debug ( {
117+ msg : "Approving tokens" ,
118+ protocolName : this . metadata . protocolName ,
119+ intentHash : parsedArgs . _hash ,
120+ adapterAddress : data . adapter . address ,
121+ } ) ;
122+
123+ const erc20Interface = Erc20__factory . createInterface ( ) ;
124+
125+ const requiredAmountsByTarget = parsedArgs . _targets . reduce < {
126+ [ tokenAddress : string ] : BigNumber ;
127+ } > ( ( acc , target , index ) => {
128+ const [ , amount ] = erc20Interface . decodeFunctionData (
129+ "transfer" ,
130+ parsedArgs . _data [ index ] ,
131+ ) as [ unknown , BigNumber ] ;
132+
133+ acc [ target ] ||= Zero ;
134+ acc [ target ] = acc [ target ] . add ( amount ) ;
135+
136+ return acc ;
137+ } , { } ) ;
138+
139+ const signer = this . multiProvider . getSigner ( data . adapter . chainName ) ;
140+ await Promise . all (
141+ Object . entries ( requiredAmountsByTarget ) . map (
142+ async ( [ target , requiredAmount ] ) => {
143+ const erc20 = Erc20__factory . connect ( target , signer ) ;
144+
145+ const tx = await erc20 . approve ( data . adapter . address , requiredAmount ) ;
146+ await tx . wait ( ) ;
147+ } ,
148+ ) ,
149+ ) ;
150+
161151 const _chainId = parsedArgs . _destinationChain . toString ( ) ;
162152
163153 const filler = this . multiProvider . getSigner ( _chainId ) ;
@@ -210,5 +200,54 @@ export class EcoFiller extends BaseFiller<Metadata, ParsedArgs, IntentData> {
210200 }
211201}
212202
213- export const create = ( multiProvider : MultiProvider ) =>
214- new EcoFiller ( multiProvider ) . create ( ) ;
203+ const enoughBalanceOnDestination : EcoRule = async ( parsedArgs , context ) => {
204+ const erc20Interface = Erc20__factory . createInterface ( ) ;
205+
206+ const requiredAmountsByTarget = parsedArgs . _targets . reduce < {
207+ [ tokenAddress : string ] : BigNumber ;
208+ } > ( ( acc , target , index ) => {
209+ const [ , amount ] = erc20Interface . decodeFunctionData (
210+ "transfer" ,
211+ parsedArgs . _data [ index ] ,
212+ ) as [ unknown , BigNumber ] ;
213+
214+ acc [ target ] ||= Zero ;
215+ acc [ target ] = acc [ target ] . add ( amount ) ;
216+
217+ return acc ;
218+ } , { } ) ;
219+
220+ const chainId = parsedArgs . _destinationChain . toString ( ) ;
221+ const fillerAddress = await context . multiProvider . getSignerAddress ( chainId ) ;
222+ const provider = context . multiProvider . getProvider ( chainId ) ;
223+
224+ for ( const tokenAddress in requiredAmountsByTarget ) {
225+ const balance = await retrieveTokenBalance (
226+ tokenAddress ,
227+ fillerAddress ,
228+ provider ,
229+ ) ;
230+
231+ if ( balance . lt ( requiredAmountsByTarget [ tokenAddress ] ) ) {
232+ return {
233+ error : `Insufficient balance on destination chain ${ chainId } for token ${ tokenAddress } ` ,
234+ success : false ,
235+ } ;
236+ }
237+ }
238+
239+ return { data : "Enough tokens to fulfill the intent" , success : true } ;
240+ } ;
241+
242+ export const create = (
243+ multiProvider : MultiProvider ,
244+ rules ?: EcoFiller [ "rules" ] ,
245+ keepBaseRules = true ,
246+ ) => {
247+ const customRules = rules ?? [ ] ;
248+
249+ return new EcoFiller (
250+ multiProvider ,
251+ keepBaseRules ? [ enoughBalanceOnDestination , ...customRules ] : customRules ,
252+ ) . create ( ) ;
253+ } ;
0 commit comments