@@ -6,7 +6,7 @@ import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers";
66// @ts -ignore
77import { generateUtil } from "eth-delegatable-utils" ;
88import { getPrivateKeys } from "../../utils/getPrivateKeys" ;
9- import { generateDelegation } from "../utils" ;
9+ import { generateDelegation , prepend0x } from "../utils" ;
1010
1111const { getSigners } = ethers ;
1212
@@ -165,6 +165,89 @@ describe("ERC20AllowanceEnforcer", () => {
165165 ) . to . be . revertedWith ( "ERC20AllowanceEnforcer:allowance-exceeded" ) ;
166166 } ) ;
167167
168+ it ( "should FAIL to transfer more than initial delegation permits" , async ( ) => {
169+ expect ( await ERC20Delegatable . balanceOf ( wallet0 . address ) ) . to . eq (
170+ ethers . utils . parseEther ( "1" )
171+ ) ;
172+
173+ // root delegation (signer will be set to the message sender and therefore tokens will transfer from signer's account)
174+ // root delegation provides allowance for 0.1
175+ const _delegation0 = generateDelegation (
176+ CONTACT_NAME ,
177+ ERC20Delegatable ,
178+ PK0 ,
179+ wallet1 . address ,
180+ [
181+ {
182+ enforcer : ERC20AllowanceEnforcer . address ,
183+ terms : ethers . utils . hexZeroPad (
184+ utils . parseEther ( "0.1" ) . toHexString ( ) ,
185+ 32
186+ ) ,
187+ } ,
188+ ]
189+ ) ;
190+
191+ const _delegationHash0 =
192+ delegatableUtils . createSignedDelegationHash ( _delegation0 ) ;
193+ const _delegationHash0Hex = prepend0x ( _delegationHash0 . toString ( "hex" ) ) ;
194+
195+ // this delegation says allowance is 0.2
196+ const _delegation1 = generateDelegation (
197+ CONTACT_NAME ,
198+ ERC20Delegatable ,
199+ PK1 ,
200+ wallet2 . address ,
201+ [
202+ {
203+ enforcer : ERC20AllowanceEnforcer . address ,
204+ terms : ethers . utils . hexZeroPad (
205+ utils . parseEther ( "0.2" ) . toHexString ( ) ,
206+ 32
207+ ) ,
208+ } ,
209+ ] ,
210+ _delegationHash0Hex
211+ ) ;
212+
213+ // invocation will try to transfer 0.2
214+ const INVOCATION_MESSAGE = {
215+ replayProtection : {
216+ nonce : "0x01" ,
217+ queue : "0x00" ,
218+ } ,
219+ batch : [
220+ {
221+ authority : [ _delegation0 , _delegation1 ] ,
222+ transaction : {
223+ to : ERC20Delegatable . address ,
224+ gasLimit : "210000000000000000" ,
225+ data : (
226+ await ERC20Delegatable . populateTransaction . transfer (
227+ wallet1 . address ,
228+ ethers . utils . parseEther ( "0.2" )
229+ )
230+ ) . data ,
231+ } ,
232+ } ,
233+ ] ,
234+ } ;
235+ const invocation = delegatableUtils . signInvocation ( INVOCATION_MESSAGE , PK2 ) ;
236+
237+ await expect (
238+ ERC20Delegatable . invoke ( [
239+ {
240+ signature : invocation . signature ,
241+ invocations : invocation . invocations ,
242+ } ,
243+ ] )
244+ ) . to . be . revertedWith ( "ERC20AllowanceEnforcer:allowance-exceeded" ) ;
245+
246+ expect ( await ERC20Delegatable . balanceOf ( wallet0 . address ) ) . to . eq (
247+ ethers . utils . parseEther ( "1" )
248+ ) ;
249+ } ) ;
250+
168251 it ( "should FAIL to INVOKE invalid method" , async ( ) => {
169252 const PK = wallet0 . _signingKey ( ) . privateKey . substring ( 2 ) ;
170253 expect ( await ERC20Delegatable . balanceOf ( wallet0 . address ) ) . to . eq (
0 commit comments