@raac/rpc 2.0.0-beta.4 → 2.0.0-beta.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/dist/RPCLibrary.js +52 -2
  2. package/dist/artifacts/mocks/core/tokens/ERC721Mock.sol/ERC721Mock.json +491 -0
  3. package/dist/configs/chains/11155111.json +2 -2
  4. package/dist/configs/chains/8453.json +29 -3
  5. package/dist/contracts/lockers/botLocker/addRewardTokens.js +21 -0
  6. package/dist/contracts/lockers/botLocker/distributeRewardToken.js +23 -0
  7. package/dist/contracts/lockers/botLocker/getConfig.js +29 -0
  8. package/dist/contracts/lockers/botLocker/getLocks.js +11 -1
  9. package/dist/contracts/lockers/botLocker/getRoles.js +22 -0
  10. package/dist/contracts/lockers/botLocker/getUnlockWindow.js +29 -0
  11. package/dist/contracts/lockers/botLocker/grantRole.js +38 -0
  12. package/dist/contracts/lockers/botLocker/hasRole.js +18 -0
  13. package/dist/contracts/lockers/botLocker/pause.js +24 -0
  14. package/dist/contracts/lockers/botLocker/rescueTokens.js +22 -0
  15. package/dist/contracts/zeno/_helpers.js +43 -0
  16. package/dist/contracts/zeno/buy.js +27 -0
  17. package/dist/contracts/zeno/getAuctionState.js +45 -0
  18. package/dist/contracts/zeno/getAuctions.js +7 -4
  19. package/dist/contracts/zeno/getBondState.js +47 -0
  20. package/dist/contracts/zeno/getPrice.js +23 -0
  21. package/dist/contracts/zeno/getZenos.js +6 -6
  22. package/dist/contracts/zeno/grantRole.js +46 -0
  23. package/dist/contracts/zeno/pause.js +42 -0
  24. package/dist/contracts/zeno/priceAt.js +20 -0
  25. package/dist/contracts/zeno/quoteBuy.js +33 -0
  26. package/dist/contracts/zeno/redeem.js +44 -0
  27. package/dist/contracts/zeno/setAuction.js +25 -0
  28. package/dist/contracts/zeno/sweepSurplus.js +26 -0
  29. package/dist/nfts/getNFTBalance.js +29 -0
  30. package/dist/nfts/transferNFT.js +34 -0
  31. package/dist/types/RPCLibrary.d.ts +51 -1
  32. package/dist/types/contracts/lockers/botLocker/addRewardTokens.d.ts +11 -0
  33. package/dist/types/contracts/lockers/botLocker/distributeRewardToken.d.ts +13 -0
  34. package/dist/types/contracts/lockers/botLocker/getConfig.d.ts +20 -0
  35. package/dist/types/contracts/lockers/botLocker/getLocks.d.ts +4 -0
  36. package/dist/types/contracts/lockers/botLocker/getRoles.d.ts +20 -0
  37. package/dist/types/contracts/lockers/botLocker/getUnlockWindow.d.ts +24 -0
  38. package/dist/types/contracts/lockers/botLocker/grantRole.d.ts +20 -0
  39. package/dist/types/contracts/lockers/botLocker/hasRole.d.ts +12 -0
  40. package/dist/types/contracts/lockers/botLocker/pause.d.ts +6 -0
  41. package/dist/types/contracts/lockers/botLocker/rescueTokens.d.ts +12 -0
  42. package/dist/types/contracts/zeno/_helpers.d.ts +17 -0
  43. package/dist/types/contracts/zeno/buy.d.ts +15 -0
  44. package/dist/types/contracts/zeno/getAuctionState.d.ts +45 -0
  45. package/dist/types/contracts/zeno/getAuctions.d.ts +3 -2
  46. package/dist/types/contracts/zeno/getBondState.d.ts +42 -0
  47. package/dist/types/contracts/zeno/getPrice.d.ts +12 -0
  48. package/dist/types/contracts/zeno/getZenos.d.ts +2 -2
  49. package/dist/types/contracts/zeno/grantRole.d.ts +22 -0
  50. package/dist/types/contracts/zeno/pause.d.ts +18 -0
  51. package/dist/types/contracts/zeno/priceAt.d.ts +20 -0
  52. package/dist/types/contracts/zeno/quoteBuy.d.ts +34 -0
  53. package/dist/types/contracts/zeno/redeem.d.ts +20 -0
  54. package/dist/types/contracts/zeno/setAuction.d.ts +13 -0
  55. package/dist/types/contracts/zeno/sweepSurplus.d.ts +14 -0
  56. package/dist/types/nfts/getNFTBalance.d.ts +13 -0
  57. package/dist/types/nfts/transferNFT.d.ts +15 -0
  58. package/dist/types/utils/artifacts.d.ts +99 -0
  59. package/dist/utils/artifacts.js +3 -0
  60. package/package.json +1 -1
@@ -22,12 +22,12 @@
22
22
  "auctionfactory": {
23
23
  "id": "auctionfactory",
24
24
  "name": "Auction Factory",
25
- "contract": "0xC644A84734A7329eE46d3B6704746179d272f990"
25
+ "contract": "0x98eDDadCfde04dC22a0e62119617e74a6Bc77313"
26
26
  },
27
27
  "zenofactory": {
28
28
  "id": "zenofactory",
29
29
  "name": "Zeno Factory",
30
- "contract": "0xa9eE59A113bCB4B2CC10f802D1efF0Bae1Ab91D2"
30
+ "contract": "0x95bD8D42f30351685e96C62EDdc0d0613bf9a87A"
31
31
  },
32
32
  "raacminter": {
33
33
  "id": "raacminter",
@@ -197,6 +197,11 @@
197
197
  "asset": "crvusd",
198
198
  "name": "RAAC NFT",
199
199
  "contract": "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9"
200
+ },
201
+ "raacbotnft": {
202
+ "id": "raacbotnft",
203
+ "name": "RAAC Bot NFT (mock)",
204
+ "contract": "0x700b6A60ce7EaaEA56F065753d8dcB9653dbAD35"
200
205
  }
201
206
  },
202
207
  "assets": {
@@ -294,6 +299,27 @@
294
299
  "symbol": "leRAAC",
295
300
  "decimals": 18,
296
301
  "contract": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853"
302
+ },
303
+ "zenocrvusd": {
304
+ "id": "zenocrvusd",
305
+ "name": "crvUSD (bond seed mock)",
306
+ "symbol": "crvUSD",
307
+ "decimals": 18,
308
+ "contract": "0x2B574555158337Cd46d47c2Ca57E4698A1f04e70"
309
+ },
310
+ "zenousdc": {
311
+ "id": "zenousdc",
312
+ "name": "USDC (bond seed mock)",
313
+ "symbol": "USDC",
314
+ "decimals": 6,
315
+ "contract": "0xcA8b49076D1A8039599e24979abf819af784c27a"
316
+ },
317
+ "zenousdt": {
318
+ "id": "zenousdt",
319
+ "name": "USDT (bond seed mock)",
320
+ "symbol": "USDT",
321
+ "decimals": 6,
322
+ "contract": "0xc039b3B46814D8388e5205D37Dd0D154D806F1f4"
297
323
  }
298
324
  },
299
325
  "lockers": {
@@ -310,7 +336,7 @@
310
336
  "raacbotlocker": {
311
337
  "id": "raacbotlocker",
312
338
  "name": "RAAC Bot Locker",
313
- "contract": "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82"
339
+ "contract": "0x8ce361602B935680E8DeC218b820ff5056BeB7af"
314
340
  }
315
341
  },
316
342
  "zap": {
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.addRewardTokens = void 0;
4
+ const _helpers_1 = require("./_helpers");
5
+ /**
6
+ * Register reward tokens that can be distributed to lockers. MANAGER_ROLE only.
7
+ * Reverts if any token is the zero address or already registered.
8
+ *
9
+ * @param chainId - The chain/network to use.
10
+ * @param tokens - ERC20 addresses to register.
11
+ * @param signer - An ethers.js Signer instance (required).
12
+ */
13
+ const addRewardTokens = async (chainId, tokens, signer) => {
14
+ if (!signer)
15
+ throw new Error("Signer is required");
16
+ const contract = await (0, _helpers_1.getBotLockerContract)(chainId, signer);
17
+ const tx = await contract.addRewardTokens(tokens);
18
+ await tx.wait();
19
+ return tx;
20
+ };
21
+ exports.addRewardTokens = addRewardTokens;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.distributeRewardToken = void 0;
4
+ const _helpers_1 = require("./_helpers");
5
+ /**
6
+ * Distribute `amount` of a registered reward token across all currently locked NFTs. DISTRIBUTOR_ROLE only.
7
+ * The signer's tokens are pulled via transferFrom, so approve the locker for `amount` first.
8
+ * Reverts when nothing is locked.
9
+ *
10
+ * @param chainId - The chain/network to use.
11
+ * @param token - Address of a registered reward token.
12
+ * @param amount - Amount to distribute, in `token` base units.
13
+ * @param signer - An ethers.js Signer instance (required).
14
+ */
15
+ const distributeRewardToken = async (chainId, token, amount, signer) => {
16
+ if (!signer)
17
+ throw new Error("Signer is required");
18
+ const contract = await (0, _helpers_1.getBotLockerContract)(chainId, signer);
19
+ const tx = await contract.distributeRewardToken(token, amount);
20
+ await tx.wait();
21
+ return tx;
22
+ };
23
+ exports.distributeRewardToken = distributeRewardToken;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getConfig = void 0;
4
+ const _helpers_1 = require("./_helpers");
5
+ /**
6
+ * Read the locker's configuration in a single call batch.
7
+ *
8
+ * @param chainId - The chain/network to use.
9
+ * @param provider - Optional ethers.js Provider instance.
10
+ * @returns The NFT collection, lock timing constants, reward tokens and pause state.
11
+ */
12
+ const getConfig = async (chainId, provider) => {
13
+ const contract = await (0, _helpers_1.getBotLockerContract)(chainId, provider);
14
+ const [nft, epochDuration, lockDurationEpochs, rewardTokens, paused] = await Promise.all([
15
+ contract.nft(),
16
+ contract.EPOCH_DURATION(),
17
+ contract.LOCK_DURATION_IN_EPOCH(),
18
+ contract.getRewardTokens(),
19
+ contract.paused(),
20
+ ]);
21
+ return {
22
+ nft,
23
+ epochDuration: Number(epochDuration),
24
+ lockDurationEpochs: Number(lockDurationEpochs),
25
+ rewardTokens: Array.from(rewardTokens),
26
+ paused,
27
+ };
28
+ };
29
+ exports.getConfig = getConfig;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getLocksByOwner = exports.getLocks = void 0;
3
+ exports.getLocksByOwner = exports.getLock = exports.getLocks = void 0;
4
+ const ethers_1 = require("ethers");
4
5
  const _helpers_1 = require("./_helpers");
5
6
  const normalize = (l) => ({
6
7
  owner: l.owner ?? l[0],
@@ -16,6 +17,15 @@ const getLocks = async (chainId, provider) => {
16
17
  return results.map(normalize);
17
18
  };
18
19
  exports.getLocks = getLocks;
20
+ /**
21
+ * Returns the lock of a single NFT, or null when it is not locked.
22
+ */
23
+ const getLock = async (chainId, tokenId, provider) => {
24
+ const contract = await (0, _helpers_1.getBotLockerContract)(chainId, provider);
25
+ const lock = normalize(await contract.locks(tokenId));
26
+ return lock.owner === ethers_1.ZeroAddress ? null : lock;
27
+ };
28
+ exports.getLock = getLock;
19
29
  /**
20
30
  * Returns every active NFT lock owned by `owner`.
21
31
  */
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getRoles = void 0;
4
+ const _helpers_1 = require("./_helpers");
5
+ /**
6
+ * Gets the access-control role identifiers used by the bot locker.
7
+ *
8
+ * @param chainId - The chain/network to use.
9
+ * @param provider - Optional ethers.js Provider instance.
10
+ * @returns The bytes32 role identifiers.
11
+ */
12
+ const getRoles = async (chainId, provider) => {
13
+ const contract = await (0, _helpers_1.getBotLockerContract)(chainId, provider);
14
+ const [defaultAdminRole, pauserRole, managerRole, distributorRole] = await Promise.all([
15
+ contract.DEFAULT_ADMIN_ROLE(),
16
+ contract.PAUSER_ROLE(),
17
+ contract.MANAGER_ROLE(),
18
+ contract.DISTRIBUTOR_ROLE(),
19
+ ]);
20
+ return { defaultAdminRole, pauserRole, managerRole, distributorRole };
21
+ };
22
+ exports.getRoles = getRoles;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getUnlockWindow = exports.BOT_LOCKER_LOCK_DURATION_EPOCHS = exports.BOT_LOCKER_EPOCH_DURATION = void 0;
4
+ /** EPOCH_DURATION on RAACBotLocker, seconds. */
5
+ exports.BOT_LOCKER_EPOCH_DURATION = 7 * 24 * 60 * 60;
6
+ /** LOCK_DURATION_IN_EPOCH on RAACBotLocker. */
7
+ exports.BOT_LOCKER_LOCK_DURATION_EPOCHS = 4;
8
+ /**
9
+ * Unlock window of a locked NFT, computed locally without an RPC call.
10
+ *
11
+ * The contract allows `unlockAndClaim` when `floor((now - lockedAt) / epochDuration)` is a non-zero multiple of `lockDurationEpochs`, so windows are `[lockedAt + k * cycle, lockedAt + k * cycle + epochDuration)` for `k >= 1`, where `cycle = lockDurationEpochs * epochDuration`. They are relative to each NFT's own `lockedAt`, not to a global epoch, and a missed window reopens one cycle later.
12
+ *
13
+ * @param lockedAt - Lock timestamp of the NFT, unix seconds (`locks(tokenId).lockedAt`, or `lockedAt` from the subgraph).
14
+ * @param now - Current time, unix seconds. Use the latest block timestamp to match the contract exactly.
15
+ * @param epochDuration - Epoch length, seconds. Defaults to the contract constant.
16
+ * @param lockDurationEpochs - Epochs per lock cycle. Defaults to the contract constant.
17
+ * @returns Whether the NFT can unlock now and the bounds of the current or next window.
18
+ */
19
+ const getUnlockWindow = (lockedAt, now, epochDuration = exports.BOT_LOCKER_EPOCH_DURATION, lockDurationEpochs = exports.BOT_LOCKER_LOCK_DURATION_EPOCHS) => {
20
+ const epochs = Math.floor((now - lockedAt) / epochDuration);
21
+ if (epochs > 0 && epochs % lockDurationEpochs === 0) {
22
+ const opensAt = lockedAt + epochs * epochDuration;
23
+ return { unlockable: true, opensAt, closesAt: opensAt + epochDuration };
24
+ }
25
+ const cycle = Math.floor(Math.max(epochs, 0) / lockDurationEpochs) + 1;
26
+ const opensAt = lockedAt + cycle * lockDurationEpochs * epochDuration;
27
+ return { unlockable: false, opensAt, closesAt: opensAt + epochDuration };
28
+ };
29
+ exports.getUnlockWindow = getUnlockWindow;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.revokeRole = exports.grantRole = void 0;
4
+ const _helpers_1 = require("./_helpers");
5
+ /**
6
+ * Grant a bot locker role. DEFAULT_ADMIN_ROLE only.
7
+ *
8
+ * @param chainId - The chain/network to use.
9
+ * @param role - The bytes32 role identifier (see `getRoles`).
10
+ * @param account - The address to grant the role to.
11
+ * @param signer - An ethers.js Signer instance (required).
12
+ */
13
+ const grantRole = async (chainId, role, account, signer) => {
14
+ if (!signer)
15
+ throw new Error("Signer is required");
16
+ const contract = await (0, _helpers_1.getBotLockerContract)(chainId, signer);
17
+ const tx = await contract.grantRole(role, account);
18
+ await tx.wait();
19
+ return tx;
20
+ };
21
+ exports.grantRole = grantRole;
22
+ /**
23
+ * Revoke a bot locker role. DEFAULT_ADMIN_ROLE only.
24
+ *
25
+ * @param chainId - The chain/network to use.
26
+ * @param role - The bytes32 role identifier (see `getRoles`).
27
+ * @param account - The address to revoke the role from.
28
+ * @param signer - An ethers.js Signer instance (required).
29
+ */
30
+ const revokeRole = async (chainId, role, account, signer) => {
31
+ if (!signer)
32
+ throw new Error("Signer is required");
33
+ const contract = await (0, _helpers_1.getBotLockerContract)(chainId, signer);
34
+ const tx = await contract.revokeRole(role, account);
35
+ await tx.wait();
36
+ return tx;
37
+ };
38
+ exports.revokeRole = revokeRole;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.hasRole = void 0;
4
+ const _helpers_1 = require("./_helpers");
5
+ /**
6
+ * Checks whether an account holds a bot locker role.
7
+ *
8
+ * @param chainId - The chain/network to use.
9
+ * @param role - The bytes32 role identifier (see `getRoles`).
10
+ * @param account - The address to check.
11
+ * @param provider - Optional ethers.js Provider instance.
12
+ * @returns True if the account holds the role.
13
+ */
14
+ const hasRole = async (chainId, role, account, provider) => {
15
+ const contract = await (0, _helpers_1.getBotLockerContract)(chainId, provider);
16
+ return contract.hasRole(role, account);
17
+ };
18
+ exports.hasRole = hasRole;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.unpause = exports.pause = void 0;
4
+ const _helpers_1 = require("./_helpers");
5
+ /** Pause lock, unlockAndClaim and claim. PAUSER_ROLE only. */
6
+ const pause = async (chainId, signer) => {
7
+ if (!signer)
8
+ throw new Error("Signer is required");
9
+ const contract = await (0, _helpers_1.getBotLockerContract)(chainId, signer);
10
+ const tx = await contract.pause();
11
+ await tx.wait();
12
+ return tx;
13
+ };
14
+ exports.pause = pause;
15
+ /** PAUSER_ROLE only. */
16
+ const unpause = async (chainId, signer) => {
17
+ if (!signer)
18
+ throw new Error("Signer is required");
19
+ const contract = await (0, _helpers_1.getBotLockerContract)(chainId, signer);
20
+ const tx = await contract.unpause();
21
+ await tx.wait();
22
+ return tx;
23
+ };
24
+ exports.unpause = unpause;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.rescueTokens = void 0;
4
+ const _helpers_1 = require("./_helpers");
5
+ /**
6
+ * Send the locker's entire balance of `token` to `recipient`. DEFAULT_ADMIN_ROLE only.
7
+ * This includes rewards lockers have not claimed yet, so later claims of that token revert until it is refilled.
8
+ *
9
+ * @param chainId - The chain/network to use.
10
+ * @param token - ERC20 address to rescue.
11
+ * @param recipient - Address receiving the balance.
12
+ * @param signer - An ethers.js Signer instance (required).
13
+ */
14
+ const rescueTokens = async (chainId, token, recipient, signer) => {
15
+ if (!signer)
16
+ throw new Error("Signer is required");
17
+ const contract = await (0, _helpers_1.getBotLockerContract)(chainId, signer);
18
+ const tx = await contract.rescueTokens(token, recipient);
19
+ await tx.wait();
20
+ return tx;
21
+ };
22
+ exports.rescueTokens = rescueTokens;
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ERC20_ABI = void 0;
7
+ exports.getZenoContract = getZenoContract;
8
+ exports.getAuctionContract = getAuctionContract;
9
+ exports.toZenoAmount = toZenoAmount;
10
+ exports.addressOrNull = addressOrNull;
11
+ const ethers_1 = require("ethers");
12
+ const chains_1 = __importDefault(require("../../configs/chains"));
13
+ const artifacts_1 = require("../../utils/artifacts");
14
+ const amount_1 = require("../../utils/amount");
15
+ /** The one ERC20 call the zeno methods make: the underlying held by a ZENO. */
16
+ exports.ERC20_ABI = ["function balanceOf(address) view returns (uint256)"];
17
+ /** A ZENO bond. Bonds are created by the factory, so the address is passed in rather than read from the config. */
18
+ function getZenoContract(chainId, zeno, runner) {
19
+ if (!runner) {
20
+ const rpc = chains_1.default[chainId].rpcs[0];
21
+ runner = new ethers_1.ethers.JsonRpcProvider(rpc);
22
+ }
23
+ return new ethers_1.ethers.Contract(zeno, (0, artifacts_1.getABI)("zeno"), runner);
24
+ }
25
+ /** A ZENO auction. Auctions are created by the factory, so the address is passed in rather than read from the config. */
26
+ function getAuctionContract(chainId, auction, runner) {
27
+ if (!runner) {
28
+ const rpc = chains_1.default[chainId].rpcs[0];
29
+ runner = new ethers_1.ethers.JsonRpcProvider(rpc);
30
+ }
31
+ return new ethers_1.ethers.Contract(auction, (0, artifacts_1.getABI)("auction"), runner);
32
+ }
33
+ /**
34
+ * A ZENO amount. ZENO takes its decimals from its underlying, so they come from the underlying's registry entry; a
35
+ * ZENO address itself is never in the registry. Falls back to 18 decimals when the underlying is not listed.
36
+ */
37
+ function toZenoAmount(chainId, underlying, value, symbol) {
38
+ return (0, amount_1.toAmount)(value, (0, amount_1.getTokenInfo)(chainId, underlying)?.decimals ?? amount_1.WAD_DECIMALS, symbol);
39
+ }
40
+ /** `ZENO.auction()` and other unset address fields read as the zero address; this maps that to null. */
41
+ function addressOrNull(address) {
42
+ return address === ethers_1.ethers.ZeroAddress ? null : address;
43
+ }
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const rpcError_1 = require("../../utils/rpcError");
4
+ const _helpers_1 = require("./_helpers");
5
+ /**
6
+ * Buys ZENO: spends exactly `paymentAmount` of the payment token, sent to the issuer, at the price of the block it is
7
+ * mined in. Needs a payment token allowance for the auction (`wallet.assets.approveAsset`). Reverts while paused,
8
+ * outside the auction window, when the ZENO out would exceed what is left, or when it is below `minZenoOut`.
9
+ * @param chainId The chain id.
10
+ * @param auction The auction address.
11
+ * @param paymentAmount Payment token to spend, in base units.
12
+ * @param minZenoOut The least ZENO to accept, in ZENO base units; `quoteBuy` sizes it.
13
+ * @param signer The buyer, who receives the ZENO.
14
+ * @returns The transaction receipt; its `ZENOPurchased` log carries the ZENO minted and the price paid.
15
+ */
16
+ async function buy(chainId, auction, paymentAmount, minZenoOut, signer) {
17
+ if (!signer)
18
+ throw new Error("Signer is required");
19
+ try {
20
+ const tx = await (0, _helpers_1.getAuctionContract)(chainId, auction, signer).buy(paymentAmount, minZenoOut);
21
+ return await tx.wait();
22
+ }
23
+ catch (error) {
24
+ throw (0, rpcError_1.toRpcError)("zeno.buy", error, { chainId, address: auction });
25
+ }
26
+ }
27
+ exports.default = buy;
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const amount_1 = require("../../utils/amount");
4
+ const rpcError_1 = require("../../utils/rpcError");
5
+ const _helpers_1 = require("./_helpers");
6
+ /**
7
+ * Reads one auction's terms and live state.
8
+ * @param chainId The chain id.
9
+ * @param auction The auction address.
10
+ * @param provider The provider to read with. Defaults to the chain's first configured RPC.
11
+ * @returns The auction's state.
12
+ */
13
+ async function getAuctionState(chainId, auction, provider) {
14
+ try {
15
+ const contract = (0, _helpers_1.getAuctionContract)(chainId, auction, provider);
16
+ const [details, paymentToken, paused, ended] = await Promise.all([
17
+ contract.getDetails(),
18
+ contract.token(),
19
+ contract.paused(),
20
+ contract.checkAuctionEnded(),
21
+ ]);
22
+ const underlying = await (0, _helpers_1.getZenoContract)(chainId, details.zenoAddress, contract.runner).underlyingAsset();
23
+ return {
24
+ auction: details.auctionAddress,
25
+ zeno: details.zenoAddress,
26
+ paymentToken,
27
+ issuer: details.issuer,
28
+ fundingMode: Number(details.fundingMode),
29
+ startTime: details.auctionStartTime,
30
+ endTime: details.auctionEndTime,
31
+ startingPrice: (0, amount_1.toTokenAmount)(chainId, paymentToken, details.startingPrice),
32
+ reservePrice: (0, amount_1.toTokenAmount)(chainId, paymentToken, details.reservePrice),
33
+ isFixedPrice: details.startingPrice === details.reservePrice,
34
+ price: (0, amount_1.toTokenAmount)(chainId, paymentToken, details.price),
35
+ totalAllocated: (0, _helpers_1.toZenoAmount)(chainId, underlying, details.totalZENOAllocated),
36
+ totalRemaining: (0, _helpers_1.toZenoAmount)(chainId, underlying, details.totalZENORemaining),
37
+ paused,
38
+ ended,
39
+ };
40
+ }
41
+ catch (error) {
42
+ throw (0, rpcError_1.toRpcError)("zeno.getAuctionState", error, { chainId, address: auction });
43
+ }
44
+ }
45
+ exports.default = getAuctionState;
@@ -9,12 +9,14 @@ const contracts_1 = require("../../utils/contracts");
9
9
  const artifacts_1 = require("../../utils/artifacts");
10
10
  const amount_1 = require("../../utils/amount");
11
11
  const rpcError_1 = require("../../utils/rpcError");
12
+ const _helpers_1 = require("./_helpers");
12
13
  /**
13
14
  * Lists every auction created by the AuctionFactory.
14
15
  * @param chainId The chain id.
15
16
  * @param provider The provider to read with. Defaults to the chain's first configured RPC.
16
- * @returns One record per auction. Price amounts use the auction's payment token, ZENO amounts the ZENO
17
- * token; decimals and symbols come from the chain config registry and fall back to 18 when the token is not listed.
17
+ * @returns One record per auction. Price amounts use the auction's payment token, ZENO amounts the ZENO's underlying,
18
+ * whose decimals ZENO shares; decimals and symbols come from the chain config registry and fall back to 18 when the
19
+ * token is not listed.
18
20
  */
19
21
  async function getAuctions(chainId, provider) {
20
22
  if (!provider) {
@@ -30,6 +32,7 @@ async function getAuctions(chainId, provider) {
30
32
  auctionContract.getDetails(),
31
33
  auctionContract.token(),
32
34
  ]);
35
+ const underlying = await (0, _helpers_1.getZenoContract)(chainId, details.zenoAddress, provider).underlyingAsset();
33
36
  return {
34
37
  auctionAddress: details.auctionAddress,
35
38
  zenoAddress: details.zenoAddress,
@@ -40,8 +43,8 @@ async function getAuctions(chainId, provider) {
40
43
  startingPrice: (0, amount_1.toTokenAmount)(chainId, tokenAddress, details.startingPrice),
41
44
  reservePrice: (0, amount_1.toTokenAmount)(chainId, tokenAddress, details.reservePrice),
42
45
  price: (0, amount_1.toTokenAmount)(chainId, tokenAddress, details.price),
43
- totalZENOAllocated: (0, amount_1.toTokenAmount)(chainId, details.zenoAddress, details.totalZENOAllocated),
44
- totalZENORemaining: (0, amount_1.toTokenAmount)(chainId, details.zenoAddress, details.totalZENORemaining),
46
+ totalZENOAllocated: (0, _helpers_1.toZenoAmount)(chainId, underlying, details.totalZENOAllocated),
47
+ totalZENORemaining: (0, _helpers_1.toZenoAmount)(chainId, underlying, details.totalZENORemaining),
45
48
  fundingMode: Number(details.fundingMode),
46
49
  };
47
50
  }));
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const ethers_1 = require("ethers");
4
+ const amount_1 = require("../../utils/amount");
5
+ const rpcError_1 = require("../../utils/rpcError");
6
+ const _helpers_1 = require("./_helpers");
7
+ /**
8
+ * Reads a ZENO bond's live state: supply, collateral and whether it can be redeemed. Collateral is read here rather
9
+ * than indexed, because top-ups are plain transfers on the underlying that no ZENO event records.
10
+ * @param chainId The chain id.
11
+ * @param zeno The ZENO bond address.
12
+ * @param provider The provider to read with. Defaults to the chain's first configured RPC.
13
+ * @returns The bond's state.
14
+ */
15
+ async function getBondState(chainId, zeno, provider) {
16
+ try {
17
+ const contract = (0, _helpers_1.getZenoContract)(chainId, zeno, provider);
18
+ const [details, underlying, auction, totalSupply, sweepableSurplus, isRedeemable] = await Promise.all([
19
+ contract.getDetails(),
20
+ contract.underlyingAsset(),
21
+ contract.auction(),
22
+ contract.totalSupply(),
23
+ contract.sweepableSurplus(),
24
+ contract.isRedeemable(),
25
+ ]);
26
+ const collateral = await new ethers_1.ethers.Contract(underlying, _helpers_1.ERC20_ABI, contract.runner).balanceOf(zeno);
27
+ return {
28
+ zeno: details.zenoAddress,
29
+ name: details.name,
30
+ symbol: details.symbol,
31
+ underlying,
32
+ auction: (0, _helpers_1.addressOrNull)(auction),
33
+ maturityDate: details.maturityDate,
34
+ isRedeemable,
35
+ totalMinted: (0, _helpers_1.toZenoAmount)(chainId, underlying, details.totalMinted, details.symbol),
36
+ totalSupply: (0, _helpers_1.toZenoAmount)(chainId, underlying, totalSupply, details.symbol),
37
+ totalRedeemed: (0, _helpers_1.toZenoAmount)(chainId, underlying, details.totalRedeemed, details.symbol),
38
+ collateral: (0, amount_1.toTokenAmount)(chainId, underlying, collateral),
39
+ sweepableSurplus: (0, amount_1.toTokenAmount)(chainId, underlying, sweepableSurplus),
40
+ isFunded: collateral >= totalSupply,
41
+ };
42
+ }
43
+ catch (error) {
44
+ throw (0, rpcError_1.toRpcError)("zeno.getBondState", error, { chainId, address: zeno });
45
+ }
46
+ }
47
+ exports.default = getBondState;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const amount_1 = require("../../utils/amount");
4
+ const rpcError_1 = require("../../utils/rpcError");
5
+ const _helpers_1 = require("./_helpers");
6
+ /**
7
+ * Reads an auction's current price. Read it right before `buy` to size `minZenoOut`: a Dutch price falls every block.
8
+ * @param chainId The chain id.
9
+ * @param auction The auction address.
10
+ * @param provider The provider to read with. Defaults to the chain's first configured RPC.
11
+ * @returns The price in payment token base units per whole ZENO.
12
+ */
13
+ async function getPrice(chainId, auction, provider) {
14
+ try {
15
+ const contract = (0, _helpers_1.getAuctionContract)(chainId, auction, provider);
16
+ const [price, paymentToken] = await Promise.all([contract.getPrice(), contract.token()]);
17
+ return (0, amount_1.toTokenAmount)(chainId, paymentToken, price);
18
+ }
19
+ catch (error) {
20
+ throw (0, rpcError_1.toRpcError)("zeno.getPrice", error, { chainId, address: auction });
21
+ }
22
+ }
23
+ exports.default = getPrice;
@@ -7,14 +7,14 @@ const ethers_1 = require("ethers");
7
7
  const chains_1 = __importDefault(require("../../configs/chains"));
8
8
  const contracts_1 = require("../../utils/contracts");
9
9
  const artifacts_1 = require("../../utils/artifacts");
10
- const amount_1 = require("../../utils/amount");
11
10
  const rpcError_1 = require("../../utils/rpcError");
11
+ const _helpers_1 = require("./_helpers");
12
12
  /**
13
13
  * Lists every ZENO bond created by the ZENOFactory.
14
14
  * @param chainId The chain id.
15
15
  * @param provider The provider to read with. Defaults to the chain's first configured RPC.
16
- * @returns One record per bond. Amounts take decimals from the chain config registry and fall back to 18 when the
17
- * bond is not listed.
16
+ * @returns One record per bond. ZENO shares its underlying's decimals, so amounts take the underlying's from the chain
17
+ * config registry and fall back to 18 when it is not listed.
18
18
  */
19
19
  async function getZenos(chainId, provider) {
20
20
  if (!provider) {
@@ -26,14 +26,14 @@ async function getZenos(chainId, provider) {
26
26
  const zenoAddresses = await zenoFactoryContract.getZENOs();
27
27
  return await Promise.all(zenoAddresses.map(async (address) => {
28
28
  const zenoContract = new ethers_1.ethers.Contract(address, (0, artifacts_1.getABI)("zeno"), provider);
29
- const details = await zenoContract.getDetails();
29
+ const [details, underlying] = await Promise.all([zenoContract.getDetails(), zenoContract.underlyingAsset()]);
30
30
  return {
31
31
  zenoAddress: details.zenoAddress,
32
32
  maturityDate: details.maturityDate,
33
33
  name: details.name,
34
34
  symbol: details.symbol,
35
- totalMinted: (0, amount_1.toTokenAmount)(chainId, details.zenoAddress, details.totalMinted),
36
- totalRedeemed: (0, amount_1.toTokenAmount)(chainId, details.zenoAddress, details.totalRedeemed),
35
+ totalMinted: (0, _helpers_1.toZenoAmount)(chainId, underlying, details.totalMinted, details.symbol),
36
+ totalRedeemed: (0, _helpers_1.toZenoAmount)(chainId, underlying, details.totalRedeemed, details.symbol),
37
37
  };
38
38
  }));
39
39
  }
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.grantRole = grantRole;
4
+ exports.revokeRole = revokeRole;
5
+ const rpcError_1 = require("../../utils/rpcError");
6
+ const _helpers_1 = require("./_helpers");
7
+ /**
8
+ * Grants an auction role, e.g. PAUSER_ROLE to a guardian bot. DEFAULT_ADMIN_ROLE only.
9
+ * @param chainId The chain id.
10
+ * @param auction The auction address.
11
+ * @param role The bytes32 role identifier: `keccak256("PAUSER_ROLE")`, or the zero hash for DEFAULT_ADMIN_ROLE.
12
+ * @param account The address to grant it to.
13
+ * @param signer A DEFAULT_ADMIN_ROLE holder.
14
+ * @returns The transaction receipt.
15
+ */
16
+ async function grantRole(chainId, auction, role, account, signer) {
17
+ if (!signer)
18
+ throw new Error("Signer is required");
19
+ try {
20
+ const tx = await (0, _helpers_1.getAuctionContract)(chainId, auction, signer).grantRole(role, account);
21
+ return await tx.wait();
22
+ }
23
+ catch (error) {
24
+ throw (0, rpcError_1.toRpcError)("zeno.grantRole", error, { chainId, address: auction });
25
+ }
26
+ }
27
+ /**
28
+ * Revokes an auction role. DEFAULT_ADMIN_ROLE only.
29
+ * @param chainId The chain id.
30
+ * @param auction The auction address.
31
+ * @param role The bytes32 role identifier: `keccak256("PAUSER_ROLE")`, or the zero hash for DEFAULT_ADMIN_ROLE.
32
+ * @param account The address to revoke it from.
33
+ * @param signer A DEFAULT_ADMIN_ROLE holder.
34
+ * @returns The transaction receipt.
35
+ */
36
+ async function revokeRole(chainId, auction, role, account, signer) {
37
+ if (!signer)
38
+ throw new Error("Signer is required");
39
+ try {
40
+ const tx = await (0, _helpers_1.getAuctionContract)(chainId, auction, signer).revokeRole(role, account);
41
+ return await tx.wait();
42
+ }
43
+ catch (error) {
44
+ throw (0, rpcError_1.toRpcError)("zeno.revokeRole", error, { chainId, address: auction });
45
+ }
46
+ }