Skip to content

Commit e2c6ffb

Browse files
authored
Fix arcade dao function encoding (#282)
1 parent a52cf67 commit e2c6ffb

File tree

4 files changed

+209
-11
lines changed

4 files changed

+209
-11
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
[
2+
{
3+
"inputs": [
4+
{ "internalType": "bytes32", "name": "_merkleRoot", "type": "bytes32" },
5+
{
6+
"internalType": "contract IERC20",
7+
"name": "_token",
8+
"type": "address"
9+
},
10+
{ "internalType": "uint256", "name": "_expiration", "type": "uint256" },
11+
{
12+
"internalType": "contract INFTBoostVault",
13+
"name": "_votingVault",
14+
"type": "address"
15+
}
16+
],
17+
"stateMutability": "nonpayable",
18+
"type": "constructor"
19+
},
20+
{ "inputs": [], "name": "AA_AlreadyClaimed", "type": "error" },
21+
{ "inputs": [], "name": "AA_ClaimingExpired", "type": "error" },
22+
{ "inputs": [], "name": "AA_ClaimingNotExpired", "type": "error" },
23+
{ "inputs": [], "name": "AA_NonParticipant", "type": "error" },
24+
{ "inputs": [], "name": "AA_NotInitialized", "type": "error" },
25+
{
26+
"inputs": [
27+
{ "internalType": "string", "name": "addressType", "type": "string" }
28+
],
29+
"name": "AA_ZeroAddress",
30+
"type": "error"
31+
},
32+
{
33+
"anonymous": false,
34+
"inputs": [
35+
{
36+
"indexed": true,
37+
"internalType": "bytes32",
38+
"name": "merkleRoot",
39+
"type": "bytes32"
40+
},
41+
{
42+
"indexed": true,
43+
"internalType": "uint256",
44+
"name": "expiration",
45+
"type": "uint256"
46+
}
47+
],
48+
"name": "SetMerkleRoot",
49+
"type": "event"
50+
},
51+
{
52+
"inputs": [{ "internalType": "address", "name": "who", "type": "address" }],
53+
"name": "authorize",
54+
"outputs": [],
55+
"stateMutability": "nonpayable",
56+
"type": "function"
57+
},
58+
{
59+
"inputs": [{ "internalType": "address", "name": "", "type": "address" }],
60+
"name": "authorized",
61+
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
62+
"stateMutability": "view",
63+
"type": "function"
64+
},
65+
{
66+
"inputs": [
67+
{ "internalType": "address", "name": "delegate", "type": "address" },
68+
{ "internalType": "uint128", "name": "totalGrant", "type": "uint128" },
69+
{
70+
"internalType": "bytes32[]",
71+
"name": "merkleProof",
72+
"type": "bytes32[]"
73+
}
74+
],
75+
"name": "claimAndDelegate",
76+
"outputs": [],
77+
"stateMutability": "nonpayable",
78+
"type": "function"
79+
},
80+
{
81+
"inputs": [
82+
{ "internalType": "address", "name": "", "type": "address" },
83+
{ "internalType": "bytes32", "name": "", "type": "bytes32" }
84+
],
85+
"name": "claimed",
86+
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
87+
"stateMutability": "view",
88+
"type": "function"
89+
},
90+
{
91+
"inputs": [{ "internalType": "address", "name": "who", "type": "address" }],
92+
"name": "deauthorize",
93+
"outputs": [],
94+
"stateMutability": "nonpayable",
95+
"type": "function"
96+
},
97+
{
98+
"inputs": [],
99+
"name": "expiration",
100+
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
101+
"stateMutability": "view",
102+
"type": "function"
103+
},
104+
{
105+
"inputs": [{ "internalType": "address", "name": "who", "type": "address" }],
106+
"name": "isAuthorized",
107+
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
108+
"stateMutability": "view",
109+
"type": "function"
110+
},
111+
{
112+
"inputs": [],
113+
"name": "owner",
114+
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
115+
"stateMutability": "view",
116+
"type": "function"
117+
},
118+
{
119+
"inputs": [
120+
{ "internalType": "address", "name": "destination", "type": "address" }
121+
],
122+
"name": "reclaim",
123+
"outputs": [],
124+
"stateMutability": "nonpayable",
125+
"type": "function"
126+
},
127+
{
128+
"inputs": [],
129+
"name": "rewardsRoot",
130+
"outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
131+
"stateMutability": "view",
132+
"type": "function"
133+
},
134+
{
135+
"inputs": [
136+
{ "internalType": "bytes32", "name": "_merkleRoot", "type": "bytes32" },
137+
{ "internalType": "uint256", "name": "_expiration", "type": "uint256" }
138+
],
139+
"name": "setMerkleRoot",
140+
"outputs": [],
141+
"stateMutability": "nonpayable",
142+
"type": "function"
143+
},
144+
{
145+
"inputs": [{ "internalType": "address", "name": "who", "type": "address" }],
146+
"name": "setOwner",
147+
"outputs": [],
148+
"stateMutability": "nonpayable",
149+
"type": "function"
150+
},
151+
{
152+
"inputs": [],
153+
"name": "token",
154+
"outputs": [
155+
{ "internalType": "contract IERC20", "name": "", "type": "address" }
156+
],
157+
"stateMutability": "view",
158+
"type": "function"
159+
},
160+
{
161+
"inputs": [],
162+
"name": "votingVault",
163+
"outputs": [
164+
{
165+
"internalType": "contract INFTBoostVault",
166+
"name": "",
167+
"type": "address"
168+
}
169+
],
170+
"stateMutability": "view",
171+
"type": "function"
172+
}
173+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { describe, expect, it } from 'vitest';
2+
import type { JSONABIArgument } from '../../../../types/Contract.types';
3+
import { encodeData } from '../../../utils/encode-decode-transaction';
4+
import abi from './arcade.abi.json';
5+
6+
describe('arcade DAO contract', () => {
7+
it('should encode [address, bytes32]', async () => {
8+
const evmAddress = '0xE38a6F2045738Ea9F5Ad425E63537BA7679Eb82e';
9+
const merkleRoot =
10+
'0x9c76bb33425ea109e9bddd5ff9e97d10de0dc8de5d123a7c288f8387a4b2ba2d';
11+
// this was captured by running it on the live network first
12+
const mockEncoded =
13+
'0x0f2d940b000000000000000000000000e38a6f2045738ea9f5ad425e63537ba7679eb82e9c76bb33425ea109e9bddd5ff9e97d10de0dc8de5d123a7c288f8387a4b2ba2d';
14+
const args = [evmAddress, merkleRoot];
15+
const jsonABIArgument = abi.find(
16+
(abi) => abi.name === 'claimed',
17+
) as JSONABIArgument;
18+
const encoded = encodeData(jsonABIArgument, args);
19+
expect(encoded).toBe(mockEncoded);
20+
});
21+
});

src/classes/test/Contract/foo.unit.test.ts

+8-5
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,20 @@ describe('foo encode', () => {
99
(abi) => abi.name === 'baz',
1010
) as JSONABIArgument;
1111
const encoded = encodeData(jsonABIArgument, [69, true]);
12+
1213
expect(encoded).toBe(
1314
'0xcdcd77c000000000000000000000000000000000000000000000000000000000000000450000000000000000000000000000000000000000000000000000000000000001',
1415
);
1516
});
1617
it('encodes "bar" function', () => {
18+
const args = [['0x010203', '0x040506']];
19+
const functionName = 'bar';
1720
const jsonABIArgument = fooABI.find(
18-
(abi) => abi.name === 'bar',
21+
(abi) => abi.name === functionName,
1922
) as JSONABIArgument;
20-
const encoded = encodeData(jsonABIArgument, ['abc', 'def']);
21-
expect(encoded).toBe(
22-
'0xfce353f661626300000000000000000000000000000000000000000000000000000000006465660000000000000000000000000000000000000000000000000000000000',
23-
);
23+
24+
// const iface = new Interface(fooABI as any);
25+
// const ethersEncoded = iface.encodeFunctionData(functionName, args);
26+
expect(() => encodeData(jsonABIArgument, args)).toThrow();
2427
});
2528
});

src/classes/utils/encode-decode-transaction.ts

+7-6
Original file line numberDiff line numberDiff line change
@@ -113,12 +113,13 @@ export function encodeData(jsonABIArgument: JSONABIArgument, args: any[]) {
113113
break;
114114
default:
115115
if (inputType.startsWith('bytes')) {
116-
// encode each character to hex
117-
const argEncoded = rawArg
118-
.split('')
119-
.map((character: string) => character.charCodeAt(0).toString(16))
120-
.join('');
121-
const paddedEncodedArg = argEncoded.padEnd(64, '0');
116+
if (Array.isArray(arg)) {
117+
throw new Error(
118+
`essential-eth does not yet support "${inputType}[]" inputs. Make a PR today!"`,
119+
);
120+
}
121+
const argEncoded = BigInt(arg).toString(16);
122+
const paddedEncodedArg = argEncoded.padStart(64, '0');
122123
return paddedEncodedArg;
123124
} else if (inputType === 'uint256') {
124125
const argEncoded = BigInt(arg).toString(16);

0 commit comments

Comments
 (0)