Skip to content

Commit 46f1884

Browse files
authored
Merge pull request #47 from kostysh/feat/upgrade-offer-hash
Feat/upgrade offer hash
2 parents c9f5354 + 1e2c3ac commit 46f1884

File tree

19 files changed

+585
-484
lines changed

19 files changed

+585
-484
lines changed

contracts/libraries/Utils.sol

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ library Utils {
1717
bytes32 public constant OFFER_TYPE_HASH =
1818
keccak256(
1919
// solhint-disable-next-line max-line-length
20-
"Offer(bytes32 id,uint256 expire,bytes32 supplierId,uint256 chainId,bytes32 requestHash,bytes32 optionsHash,bytes32 paymentHash,bytes32 cancelHash,bool transferable,uint256 checkIn)"
20+
"Offer(bytes32 id,uint256 expire,bytes32 supplierId,uint256 chainId,bytes32 requestHash,bytes32 optionsHash,bytes32 paymentHash,bytes32 cancelHash,bool transferable,uint256 checkIn,uint256 checkOut)"
2121
);
2222

2323
bytes32 public constant CHECK_IN_TYPE_HASH =
@@ -180,7 +180,8 @@ library Utils {
180180
_offer.paymentHash,
181181
_offer.cancelHash,
182182
_offer.transferable,
183-
_offer.checkIn
183+
_offer.checkIn,
184+
_offer.checkOut
184185
)
185186
);
186187
}

deploy/001.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
protocolFee,
1010
retailerFee,
1111
minDeposit,
12-
} from "../utils/constants";
12+
} from "../temp/utils/constants";
1313

1414
const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
1515
const { network, deployments, getNamedAccounts } = hre;

deploy/002.ts

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {
1414
protocolFee,
1515
retailerFee,
1616
minDeposit,
17-
} from "../utils/constants";
17+
} from "../utils";
1818

1919
const setupToken = async (
2020
proxySettings: { owner: string; proxyContract: string },
@@ -29,10 +29,10 @@ const setupToken = async (
2929
contract: contractName,
3030
proxy: {
3131
...proxySettings,
32-
execute: {
33-
methodName: "initialize",
34-
args: [tokenName, tokenSymbol, owner],
35-
},
32+
// execute: {
33+
// methodName: "initialize",
34+
// args: [tokenName, tokenSymbol, owner],
35+
// },
3636
},
3737
from: owner,
3838
log: true,
@@ -128,19 +128,19 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
128128
const protocolConfig = await deploy("Config", {
129129
proxy: {
130130
...PROXY_SETTINGS_WITH_UPGRADE,
131-
execute: {
132-
methodName: "initialize",
133-
args: [
134-
owner,
135-
lif.address,
136-
claimPeriod,
137-
protocolFee,
138-
retailerFee,
139-
owner,
140-
kindsArr,
141-
kindsArr.map(() => minDeposit), // same limit for all
142-
],
143-
},
131+
// execute: {
132+
// methodName: "initialize",
133+
// args: [
134+
// owner,
135+
// lif.address,
136+
// claimPeriod,
137+
// protocolFee,
138+
// retailerFee,
139+
// owner,
140+
// kindsArr,
141+
// kindsArr.map(() => minDeposit), // same limit for all
142+
// ],
143+
// },
144144
},
145145
from: owner,
146146
log: true,
@@ -158,10 +158,10 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
158158
const entities = await deploy("EntitiesRegistry", {
159159
proxy: {
160160
...PROXY_SETTINGS_WITH_UPGRADE,
161-
execute: {
162-
methodName: "initialize",
163-
args: [owner, protocolConfig.address],
164-
},
161+
// execute: {
162+
// methodName: "initialize",
163+
// args: [owner, protocolConfig.address],
164+
// },
165165
},
166166
from: owner,
167167
log: true,
@@ -179,16 +179,16 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
179179
const market = await deploy("Market", {
180180
proxy: {
181181
...PROXY_SETTINGS_WITH_UPGRADE,
182-
execute: {
183-
methodName: "initialize",
184-
args: [
185-
owner,
186-
eip712name,
187-
eip712version,
188-
protocolConfig.address,
189-
entities.address,
190-
],
191-
},
182+
// execute: {
183+
// methodName: "initialize",
184+
// args: [
185+
// owner,
186+
// eip712name,
187+
// eip712version,
188+
// protocolConfig.address,
189+
// entities.address,
190+
// ],
191+
// },
192192
},
193193
from: owner,
194194
log: true,

deployments/polzktest/Market.json

Lines changed: 3 additions & 13 deletions
Large diffs are not rendered by default.

deployments/polzktest/Market_Implementation.json

Lines changed: 79 additions & 79 deletions
Large diffs are not rendered by default.

deployments/polzktest/solcInputs/21eac61dc4f78e216bbddc7cc9f68411.json

Lines changed: 119 additions & 0 deletions
Large diffs are not rendered by default.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@
5959
"@typechain/hardhat": "^6.1.6",
6060
"@typechain/ethers-v5": "^10.2.1",
6161
"@typechain/ethers-v6": "^0.3.2",
62-
"dotenv": "^16.0.3"
62+
"dotenv": "^16.0.3",
63+
"viem": "^0.3.37"
6364
},
6465
"dependencies": {
6566
"@openzeppelin/contracts-upgradeable": "^4.8.3"

package/src/constants.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,30 @@ export const kinds = {
66
retailer: '0x72657461696c6572000000000000000000000000000000000000000000000000',
77
};
88

9-
// ethers.solidityPackedKeccak256(
9+
// viem.encodePacked(
1010
// ['string'],
1111
// ['PaymentOption(bytes32 id,uint256 price,address asset)'],
1212
// );
1313
export const PAYMENT_OPTION_TYPE_HASH =
1414
'0x2f8fc0b3ad3f58f6deb367673d38e4112a3c8c64de033c5b780b84ef8f67cde6';
1515

16-
// ethers.solidityPackedKeccak256(
16+
// viem.encodePacked(
1717
// ['string'],
1818
// ['CancelOption(uint256 time,uint256 penalty)'],
1919
// );
2020
export const CANCEL_OPTION_TYPE_HASH =
2121
'0x8ea27057ea8a0239f02c8b75748218a035a5a2a2a0785b53aaa99af91ff538c5';
2222

23-
// ethers.solidityPackedKeccak256(
23+
// viem.encodePacked(
2424
// ['string'],
2525
// [
2626
// 'Offer(bytes32 id,uint256 expire,bytes32 supplierId,uint256 chainId,bytes32 requestHash,bytes32 optionsHash,bytes32 paymentHash,bytes32 cancelHash,bool transferable,uint256 checkIn)',
2727
// ],
2828
// );
2929
export const OFFER_TYPE_HASH =
30-
'0xcf2addd2f89a78825d3f130a17e47b4e9963adfd09837fa9c454569faa073354';
30+
'0x4fb12343a6f44152999c71291770d97fc1eace9d7d04889330d5a6d1af4a57c7';
3131

32-
// ethers.solidityPackedKeccak256(
32+
// viem.encodePacked(
3333
// ['string'],
3434
// [
3535
// 'Voucher(bytes32 id,address signer)',

package/src/hash.ts

Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
import { Hash, Address, keccak256, toHex, stringify, encodePacked } from 'viem';
2+
import {
3+
CANCEL_OPTION_TYPE_HASH,
4+
OFFER_TYPE_HASH,
5+
PAYMENT_OPTION_TYPE_HASH,
6+
} from './constants.js';
7+
8+
/** Offered payment option type */
9+
export interface PaymentOption {
10+
/** Unique payment option Id */
11+
id: Hash;
12+
/** Asset price in WEI */
13+
price: bigint;
14+
/** ERC20 asset contract address */
15+
asset: Address;
16+
}
17+
18+
/** Offered cancellation option type */
19+
export interface CancelOption {
20+
/** Seconds before checkIn */
21+
time: bigint;
22+
/** Percents of total sum */
23+
penalty: bigint;
24+
}
25+
26+
/** Unsigned offer payload type */
27+
export interface UnsignedOfferPayload extends Record<string, unknown> {
28+
/** Unique Offer Id */
29+
id: Hash;
30+
/** Expiration time */
31+
expire: bigint;
32+
/** Unique supplier Id registered on the protocol contract */
33+
supplierId: Hash;
34+
/** Target network chain Id */
35+
chainId: bigint;
36+
/** <keccak256(request.hash())> */
37+
requestHash: Hash;
38+
/** <keccak256(hash(offer.options))> */
39+
optionsHash: Hash;
40+
/** <keccak256(hash(offer.payment))> */
41+
paymentHash: Hash;
42+
/** <keccak256(hash(offer.cancel || []))> */
43+
cancelHash: Hash;
44+
/** Makes the deal NFT transferable or not */
45+
transferable: boolean;
46+
/** Check-in time in seconds */
47+
checkIn: bigint;
48+
/** Check-out time in seconds */
49+
checkOut: bigint;
50+
}
51+
52+
/**
53+
* Converts an object that contains bigint values to a JSON string representation.
54+
*
55+
* @param {unknown} data The data to stringify.
56+
* @returns {string} The JSON string representation of the data.
57+
*/
58+
export { stringify };
59+
60+
/**
61+
* Generates simple unique Id
62+
*
63+
* @param {number} [length=14] Default is `14`
64+
* @returns {string}
65+
*/
66+
export const simpleUid = (length = 14): string => {
67+
if (length < 5 || length > 14) {
68+
throw new Error('Length value must be between 5 and 14');
69+
}
70+
return Math.random()
71+
.toString(16)
72+
.replace('.', '')
73+
.split('')
74+
.sort(() => (Math.random() > 0.5 ? 1 : -1))
75+
.join('')
76+
.slice(0, length);
77+
};
78+
79+
/**
80+
* Generates random salt (bytes32 string)
81+
*
82+
* @returns {Hash}
83+
*/
84+
export const randomSalt = (): Hash => keccak256(toHex(simpleUid()));
85+
86+
/**
87+
* Computes the keccak256 hash of an object.
88+
*
89+
* @param {unknown} data The data object to hash.
90+
* @returns {Hash} The keccak256 hash of the data.
91+
*/
92+
export const hashObject = (data: unknown): Hash => {
93+
return keccak256(toHex(stringify(data)));
94+
};
95+
96+
/**
97+
* Computes the keccak256 hash of a PaymentOption object.
98+
*
99+
* @param {PaymentOption} option The PaymentOption object to hash.
100+
* @returns {Hash} The keccak256 hash of the PaymentOption.
101+
*/
102+
export const hashPaymentOption = (option: PaymentOption): Hash => {
103+
return keccak256(
104+
encodePacked(
105+
['bytes32', 'bytes32', 'uint256', 'address'],
106+
[PAYMENT_OPTION_TYPE_HASH, option.id, option.price, option.asset],
107+
),
108+
);
109+
};
110+
111+
/**
112+
* Computes the keccak256 hash of a CancelOption object.
113+
*
114+
* @param {CancelOption} option The CancelOption object to hash.
115+
* @returns {Hash} The keccak256 hash of the CancelOption.
116+
*/
117+
export const hashCancelOption = (option: CancelOption): Hash => {
118+
return keccak256(
119+
encodePacked(
120+
['bytes32', 'uint256', 'uint256'],
121+
[CANCEL_OPTION_TYPE_HASH, option.time, option.penalty],
122+
),
123+
);
124+
};
125+
126+
/**
127+
* Computes the keccak256 hash of an array of PaymentOption objects.
128+
*
129+
* @param {PaymentOption[]} options The array of PaymentOption objects to hash.
130+
* @returns {Hash} The keccak256 hash of the PaymentOption array.
131+
*/
132+
export const hashPaymentOptionArray = (options: PaymentOption[]): Hash => {
133+
const hashes: Hash[] = [];
134+
135+
for (let i = 0; i < options.length; i++) {
136+
hashes[i] = hashPaymentOption(options[i]);
137+
}
138+
139+
return keccak256(encodePacked(['bytes32[]'], [hashes]));
140+
};
141+
142+
/**
143+
* Computes the keccak256 hash of an array of CancelOption objects.
144+
*
145+
* @param {CancelOption[]} options The array of CancelOption objects to hash.
146+
* @returns {Hash} The keccak256 hash of the CancelOption array.
147+
*/
148+
export const hashCancelOptionArray = (options: CancelOption[]): Hash => {
149+
const hashes: Hash[] = [];
150+
151+
for (let i = 0; i < options.length; i++) {
152+
hashes[i] = hashCancelOption(options[i]);
153+
}
154+
155+
return keccak256(encodePacked(['bytes32[]'], [hashes]));
156+
};
157+
158+
/**
159+
* Computes the keccak256 hash of an UnsignedOfferPayload object.
160+
*
161+
* @param {UnsignedOfferPayload} payload The UnsignedOfferPayload object to hash.
162+
* @returns {Hash} The keccak256 hash of the UnsignedOfferPayload.
163+
*/
164+
export const hashOfferPayload = (payload: UnsignedOfferPayload): Hash => {
165+
return keccak256(
166+
encodePacked(
167+
[
168+
'bytes32',
169+
'bytes32',
170+
'uint256',
171+
'bytes32',
172+
'uint256',
173+
'bytes32',
174+
'bytes32',
175+
'bytes32',
176+
'bytes32',
177+
'bool',
178+
'uint256',
179+
'uint256',
180+
],
181+
[
182+
OFFER_TYPE_HASH,
183+
payload.id,
184+
payload.expire,
185+
payload.supplierId,
186+
payload.chainId,
187+
payload.requestHash,
188+
payload.optionsHash,
189+
payload.paymentHash,
190+
payload.cancelHash,
191+
payload.transferable,
192+
payload.checkIn,
193+
payload.checkOut,
194+
],
195+
),
196+
);
197+
};
198+
199+
/**
200+
* Computes the keccak256 hash of a CheckInOut voucher.
201+
*
202+
* @param {string} offerId The ID of the offer.
203+
* @param {string} signer The signer's address.
204+
* @returns {Hash} The keccak256 hash of the CheckInOut operation.
205+
*/
206+
export const hashCheckInOut = (offerId: Hash, signer: Address): Hash => {
207+
return keccak256(
208+
encodePacked(['bytes32', 'bytes32', 'address'], [OFFER_TYPE_HASH, offerId, signer]),
209+
);
210+
};

package/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ export {
1616
};
1717
export * from './constants.js';
1818
export * from '../wagmi/index.js';
19+
export * from './hash.js';

0 commit comments

Comments
 (0)