@@ -27,6 +27,7 @@ describe("CentralPaymentsManager", function () {
27
27
let basicTm ;
28
28
let weth ;
29
29
let centralPaymentsManager ;
30
+ let permissionsRegistry ;
30
31
31
32
let wethMetaTx ;
32
33
@@ -66,7 +67,7 @@ describe("CentralPaymentsManager", function () {
66
67
// deploy weth, fanA will start with 100 wETH, also whitelist wETH on permissions registry
67
68
weth = await WETH . deploy ( highlightBeaconAdmin . address ) ;
68
69
await weth . deployed ( ) ;
69
- const permissionsRegistry = new ethers . Contract ( await factory . permissionsRegistry ( ) , IPermissionsRegistryABI , permissionsRegistryAdmin ) ;
70
+ permissionsRegistry = new ethers . Contract ( await factory . permissionsRegistry ( ) , IPermissionsRegistryABI , permissionsRegistryAdmin ) ;
70
71
const tx = await permissionsRegistry . whitelistCurrency ( weth . address ) ;
71
72
await tx . wait ( ) ;
72
73
@@ -97,7 +98,7 @@ describe("CentralPaymentsManager", function () {
97
98
basicTm = deployedBasicTm
98
99
} )
99
100
100
- describe ( "Purchase" , function ( ) {
101
+ describe ( "Purchase with minimal forwarder " , function ( ) {
101
102
it ( "Platform executor should be able to execute a well-formed and signed purchase" , async function ( ) {
102
103
const listing = {
103
104
community,
@@ -125,7 +126,7 @@ describe("CentralPaymentsManager", function () {
125
126
fanA ,
126
127
fanA . address ,
127
128
transferToPlatformData ,
128
- firstNonce + 1
129
+ firstNonce . toNumber ( ) + 1
129
130
) ;
130
131
131
132
// construct signed request from executor, moving tokens out of vault to purchaser
@@ -197,18 +198,98 @@ describe("CentralPaymentsManager", function () {
197
198
} )
198
199
} )
199
200
200
- // meta tx related failures / successes
201
- // low gas
202
- // wrong signer
203
- // wrong nonce
201
+ describe ( "Purchase with permissioned CentralPaymentsManager" , function ( ) {
202
+ beforeEach ( async function ( ) {
203
+ // whitelist the central payments manager as an executor on the PermissionsRegistry which is what makes this approach possible
204
+ expect ( await permissionsRegistry . addPlatformExecutor ( centralPaymentsManager . address ) )
205
+ . to . emit ( permissionsRegistry , "PlatformExecutorAdded" )
206
+ . withArgs ( centralPaymentsManager . address )
207
+ } )
204
208
205
- // when currency isn't whitelisted
209
+ it ( "Platform executor should be able to execute a well-formed and signed purchase" , async function ( ) {
210
+ const saleItem = {
211
+ community : community . address ,
212
+ tokenIds : [ 1 , 101 ] ,
213
+ amounts : [ 1 , 1 ] ,
214
+ price : 2 , // wETH
215
+ vault : vault . address ,
216
+ transferData : ethers . utils . arrayify ( "0x" )
217
+ }
218
+ const wETHWei = ethers . utils . parseUnits ( saleItem . price . toString ( ) , 18 ) ;
219
+ const wETHWeiToCreator = wETHWei . mul ( 97 ) . div ( 100 ) ;
220
+ const wETHWeiToPlatform = wETHWei . mul ( 3 ) . div ( 100 ) ;
221
+ const firstNonce = await wethMetaTx . contract . getNonce ( fanA . address ) ;
206
222
207
- // when caller isn't executor
223
+ // construct signed request from purchaser, sending 97% of price to creator
224
+ const transferToCreatorData = await weth . interface . encodeFunctionData ( "transfer" , [ creatorA . address , wETHWeiToCreator . toString ( ) ] ) ;
225
+ const purchaseToCreatorMetaTxPacket = await wethMetaTx . signWETHMetaTxRequest (
226
+ fanA ,
227
+ fanA . address ,
228
+ transferToCreatorData ,
229
+ firstNonce
230
+ ) ;
231
+
232
+ // construct signed request from purchaser, sending 3% of price to platform (vault in this case)
233
+ const transferToPlatformData = await weth . interface . encodeFunctionData ( "transfer" , [ vault . address , wETHWeiToPlatform . toString ( ) ] ) ;
234
+ const purchaseToPlatformMetaTxPacket = await wethMetaTx . signWETHMetaTxRequest (
235
+ fanA ,
236
+ fanA . address ,
237
+ transferToPlatformData ,
238
+ firstNonce . toNumber ( ) + 1
239
+ ) ;
208
240
209
- // with multiple token amounts
241
+ // replicating contract verification - equivalent in our backend
242
+ const transferToCreatorMetaTx = {
243
+ nonce : firstNonce . toString ( ) ,
244
+ from : fanA . address ,
245
+ functionSignature : transferToCreatorData
246
+ }
247
+ const transferToPlatformMetaTx = {
248
+ nonce : ( firstNonce + 1 ) . toString ( ) ,
249
+ from : fanA . address ,
250
+ functionSignature : transferToPlatformData
251
+ }
252
+ expect (
253
+ wethMetaTx . verify (
254
+ fanA . address ,
255
+ transferToCreatorMetaTx ,
256
+ ethers . utils . joinSignature ( { r : purchaseToCreatorMetaTxPacket . sigR , s : purchaseToCreatorMetaTxPacket . sigS , v : purchaseToCreatorMetaTxPacket . sigV } )
257
+ )
258
+ )
259
+ expect (
260
+ wethMetaTx . verify (
261
+ fanA . address ,
262
+ transferToPlatformMetaTx ,
263
+ ethers . utils . joinSignature ( { r : purchaseToPlatformMetaTxPacket . sigR , s : purchaseToPlatformMetaTxPacket . sigS , v : purchaseToPlatformMetaTxPacket . sigV } )
264
+ )
265
+ )
266
+
267
+ // purchase
268
+ const expectedPriceInWei = ethers . utils . parseUnits ( saleItem . price . toString ( ) ) ;
269
+ saleItem . price = expectedPriceInWei ;
270
+ await expect ( centralPaymentsManager . purchaseTokenWithMetaTxSupportedCurrencyAndPermissionedExecutor (
271
+ weth . address ,
272
+ fanA . address ,
273
+ saleItem ,
274
+ purchaseToCreatorMetaTxPacket ,
275
+ purchaseToPlatformMetaTxPacket
276
+ ) ) . to . emit ( centralPaymentsManager , "CentralSale" )
277
+ . withArgs (
278
+ ethers . utils . getAddress ( community . address ) ,
279
+ fanA . address ,
280
+ weth . address ,
281
+ expectedPriceInWei ,
282
+ saleItem . tokenIds
283
+ ) ;
210
284
211
- // invalid after verification from currency! since there's no external verify function on wETH
285
+ // validate:
286
+ expect ( ( await weth . balanceOf ( creatorA . address ) ) . toString ( ) ) . to . equal ( wETHWeiToCreator . mul ( 2 ) ) ;
287
+ expect ( ( await weth . balanceOf ( vault . address ) ) . toString ( ) ) . to . equal ( wETHWeiToPlatform . mul ( 2 ) ) ;
288
+ expect ( await weth . balanceOf ( fanA . address ) ) . to . equal ( ethers . BigNumber . from ( "100000000000000000000" ) . sub ( wETHWei . mul ( 2 ) ) ) ;
289
+ expect ( await community . balanceOfBatch ( [ fanA . address , fanA . address ] , saleItem . tokenIds ) ) . to . eql ( saleItem . amounts . map ( amount => ethers . BigNumber . from ( amount ) ) ) ;
290
+ // if passed in approval for OS, OS is approved
291
+ } )
292
+ } )
212
293
} )
213
294
214
295
0 commit comments