@venusprotocol/liquidity-hub 2.1.0-dev.6 → 2.1.0-dev.8
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.
- package/README.md +17 -13
- package/contracts/YieldGroup/YieldGroup.sol +1 -1
- package/contracts/YieldGroup/YieldGroupCentrifuge.sol +7 -0
- package/contracts/YieldGroup/YieldGroupFRV.sol +1 -0
- package/contracts/YieldGroup/base/NavGuard.sol +5 -4
- package/contracts/YieldGroup/base/YieldGroupBase.sol +95 -9
- package/contracts/YieldGroup/base/YieldGroupBaseStorage.sol +10 -2
- package/contracts/adapters/AdapterCentrifuge.sol +16 -1
- package/contracts/adapters/AdapterCoreV1.sol +29 -15
- package/contracts/adapters/AdapterFRV.sol +17 -7
- package/contracts/adapters/AdapterFlux.sol +15 -3
- package/contracts/adapters/AdapterSpokeV1.sol +15 -3
- package/contracts/interfaces/IMigrator.sol +8 -6
- package/contracts/interfaces/INavGuard.sol +9 -8
- package/contracts/interfaces/IResourceAdapter.sol +12 -3
- package/contracts/interfaces/IYieldGroupBase.sol +56 -7
- package/contracts/interfaces/external/IVToken.sol +9 -0
- package/contracts/migrator/Migrator.sol +21 -9
- package/deployments/bscmainnet/AdapterCoreV1.json +26 -2
- package/deployments/bscmainnet/AdapterFRV.json +26 -2
- package/deployments/bscmainnet/AdapterFlux.json +26 -2
- package/deployments/bscmainnet/AdapterSpokeV1.json +26 -2
- package/deployments/bscmainnet/Migrator.json +28 -4
- package/deployments/bscmainnet/YieldGroupCoreImpl.json +69 -2
- package/deployments/bscmainnet/YieldGroupFRVImpl.json +69 -2
- package/deployments/bscmainnet/YieldGroupFluxImpl.json +69 -2
- package/deployments/bscmainnet/YieldGroupSpokeImpl.json +69 -2
- package/deployments/bscmainnet_addresses.json +9 -9
- package/deployments/bsctestnet/AdapterCoreV1.json +26 -2
- package/deployments/bsctestnet/AdapterFRV.json +26 -2
- package/deployments/bsctestnet/AdapterFlux.json +26 -2
- package/deployments/bsctestnet/AdapterSpokeV1.json +26 -2
- package/deployments/bsctestnet/Migrator.json +28 -4
- package/deployments/bsctestnet/YieldGroupCoreImpl.json +69 -2
- package/deployments/bsctestnet/YieldGroupFRVImpl.json +69 -2
- package/deployments/bsctestnet/YieldGroupFluxImpl.json +69 -2
- package/deployments/bsctestnet/YieldGroupSpokeImpl.json +69 -2
- package/deployments/bsctestnet_addresses.json +9 -9
- package/package.json +1 -1
|
@@ -7,8 +7,10 @@ pragma solidity 0.8.25;
|
|
|
7
7
|
* @notice One-click migration from an existing Venus Core position into a Liquidity Hub. In a
|
|
8
8
|
* single atomic transaction the Migrator pulls a user's Core vToken, redeems it to the
|
|
9
9
|
* underlying, and deposits that into the matching Hub, minting share tokens to `receiver`.
|
|
10
|
-
* @dev A single immutable, permissionless deployment serves every Hub — the target is
|
|
11
|
-
* call via the `hub` argument
|
|
10
|
+
* @dev A single immutable, permissionless deployment serves every registered Hub — the target is
|
|
11
|
+
* chosen per call via the `hub` argument and must be present in the HubRegistry, so a migration
|
|
12
|
+
* can only ever land in a governance-registered Hub. Two paths exist because Venus splits its
|
|
13
|
+
* markets by asset type:
|
|
12
14
|
* ERC-20-backed markets (vUSDT, vUSDC, ...) go through {migrateFromCore}; the native market
|
|
13
15
|
* (vBNB) redeems raw BNB and so has the dedicated {migrateFromCoreBNB} path that wraps to WBNB
|
|
14
16
|
* before depositing into the WBNB Hub.
|
|
@@ -36,6 +38,8 @@ interface IMigrator {
|
|
|
36
38
|
error ZeroAddress();
|
|
37
39
|
/// @notice A required amount argument was zero.
|
|
38
40
|
error ZeroAmount();
|
|
41
|
+
/// @notice The target `hub` is not a governance-registered Hub in the HubRegistry.
|
|
42
|
+
error HubNotRegistered(address hub);
|
|
39
43
|
/// @notice The vToken's underlying does not match the Hub's asset.
|
|
40
44
|
error AssetMismatch(address vTokenUnderlying, address hubAsset);
|
|
41
45
|
/// @notice The Core market returned a non-zero (failure) error code on redeem.
|
|
@@ -44,8 +48,6 @@ interface IMigrator {
|
|
|
44
48
|
error NothingReceived();
|
|
45
49
|
/// @notice The minted shares were below the caller's `minShares` floor.
|
|
46
50
|
error InsufficientShares(uint256 shares, uint256 minShares);
|
|
47
|
-
/// @notice The native (vBNB → WBNB) path is unavailable: this deployment has no WBNB/vBNB wired.
|
|
48
|
-
error BNBMigrationUnsupported();
|
|
49
51
|
/// @notice Native value was received from an address other than the configured vBNB market.
|
|
50
52
|
error OnlyVBNB();
|
|
51
53
|
|
|
@@ -95,8 +97,8 @@ interface IMigrator {
|
|
|
95
97
|
/**
|
|
96
98
|
* @notice Migrate a native vBNB position into the WBNB Hub.
|
|
97
99
|
* @dev Caller must first `approve` this Migrator to transfer `vBNBAmount` of the configured
|
|
98
|
-
* vBNB market. The redeemed BNB is wrapped to WBNB before deposit. Reverts unless
|
|
99
|
-
*
|
|
100
|
+
* vBNB market. The redeemed BNB is wrapped to WBNB before deposit. Reverts unless `hub` is a
|
|
101
|
+
* registered WBNB Hub (`IHub(hub).asset() == WBNB`) and `shares >= minShares`.
|
|
100
102
|
* This is the no-consent path — use {migrateFromCoreBNBWithConsent} to record consent.
|
|
101
103
|
* @param vBNBAmount vBNB receipts to pull and redeem.
|
|
102
104
|
* @param hub The WBNB Hub to deposit into.
|
|
@@ -9,8 +9,9 @@ pragma solidity 0.8.25;
|
|
|
9
9
|
* @dev The band vouches for a value: the last counterparty figure we accepted, grown at the
|
|
10
10
|
* expected rate, plus whatever we have moved in or out since. Valuation is held a gap either
|
|
11
11
|
* side of that, `min(max(observed, floor), cap)`, and never reverts. The gaps are a percentage
|
|
12
|
-
* of
|
|
13
|
-
* the
|
|
12
|
+
* of `anchor`. Our own moves shift only `centre`, so they do not widen the gaps until the next
|
|
13
|
+
* re-anchor, which adopts the whole position as the new `anchor`. Take everything out and the
|
|
14
|
+
* band closes; a deposit or governance reopens it.
|
|
14
15
|
*
|
|
15
16
|
* It bounds value, not price: a position marked as `quantity x price` can be inflated
|
|
16
17
|
* through either factor. Value is the product plus whatever has no price at all, so one band
|
|
@@ -46,9 +47,9 @@ interface INavGuard {
|
|
|
46
47
|
* `anchor` and `centre` are stored as of `driftFrom`, and each grows at `driftBps` from
|
|
47
48
|
* there when read. A closed band has both at zero: every armed side then values the
|
|
48
49
|
* position at nothing, and only a deposit or {setNavGuardSnapshot} reopens it.
|
|
49
|
-
* @param anchor The
|
|
50
|
-
*
|
|
51
|
-
*
|
|
50
|
+
* @param anchor The whole position value accepted at the last re-anchor, or forced by
|
|
51
|
+
* governance, less what withdrawals have since taken past our own deposits. Never above
|
|
52
|
+
* `centre`. Both gaps are sized to it.
|
|
52
53
|
* @param centre `anchor` plus our own deposits since. What valuation is held around.
|
|
53
54
|
* @param anchoredAt When `anchor` was last set. `interval` is measured from here, and only a
|
|
54
55
|
* re-anchor moves it, so our own flows can never delay or bring one forward.
|
|
@@ -124,10 +125,10 @@ interface INavGuard {
|
|
|
124
125
|
|
|
125
126
|
/**
|
|
126
127
|
* @notice We moved value into or out of a resource, and its centre moved by exactly that. The
|
|
127
|
-
* clock is untouched, and the anchor moves only when a withdrawal
|
|
128
|
-
*
|
|
128
|
+
* clock is untouched, and the anchor moves only when a withdrawal takes more than our
|
|
129
|
+
* own deposits since the last re-anchor.
|
|
129
130
|
* @param resource Resource whose centre moved.
|
|
130
|
-
* @param anchor The
|
|
131
|
+
* @param anchor The anchor after the move. Zero right after a deposit means the
|
|
131
132
|
* deposit opened the band, and the band has no width until its first re-anchor.
|
|
132
133
|
* @param centre New stored centre, before drift.
|
|
133
134
|
*/
|
|
@@ -103,6 +103,16 @@ interface IResourceAdapter {
|
|
|
103
103
|
*/
|
|
104
104
|
function totalAssets(address resource, address holder) external view returns (uint256 value);
|
|
105
105
|
|
|
106
|
+
/**
|
|
107
|
+
* @notice Underlying value of `shares` receipt tokens of `resource`, priced exactly as
|
|
108
|
+
* {totalAssets} prices a holder's balance. Lets the YieldGroup value the receipts it
|
|
109
|
+
* minted itself rather than everything its wallet happens to hold.
|
|
110
|
+
* @param resource Underlying yield protocol address.
|
|
111
|
+
* @param shares Receipt-token amount to price, in the resource's own units.
|
|
112
|
+
* @return value Underlying units `shares` are worth.
|
|
113
|
+
*/
|
|
114
|
+
function receiptValue(address resource, uint256 shares) external view returns (uint256 value);
|
|
115
|
+
|
|
106
116
|
/**
|
|
107
117
|
* @notice Spare deposit headroom on `resource` right now (capacity remaining before the
|
|
108
118
|
* resource rejects mint via its own caps or pause).
|
|
@@ -137,9 +147,8 @@ interface IResourceAdapter {
|
|
|
137
147
|
/**
|
|
138
148
|
* @notice Raw receipt-token balance `holder` owns via `resource` (vToken / fToken / FRV
|
|
139
149
|
* shares), in receipt-token units — NOT underlying value.
|
|
140
|
-
* @dev
|
|
141
|
-
*
|
|
142
|
-
* would let removal orphan those receipt tokens; reading the raw balance closes that gap.
|
|
150
|
+
* @dev In share units so a sub-unit residual still reads as non-zero where a value read would
|
|
151
|
+
* round it to 0.
|
|
143
152
|
* @param resource Underlying yield protocol address.
|
|
144
153
|
* @param holder Address whose receipt balance to read (the YieldGroup).
|
|
145
154
|
* @return shares Receipt-token units `holder` holds in this resource.
|
|
@@ -138,6 +138,16 @@ interface IYieldGroupBase {
|
|
|
138
138
|
*/
|
|
139
139
|
event Swept(address indexed token, address indexed to, uint256 amount);
|
|
140
140
|
|
|
141
|
+
/**
|
|
142
|
+
* @notice Governance synced the tracked receipt balance of `resource` with what it holds, so
|
|
143
|
+
* receipt tokens that arrived outside the deposit path now count toward the Hub's share
|
|
144
|
+
* price, up to the cap the sync was given.
|
|
145
|
+
* @param resource Resource whose tracked balance was synced.
|
|
146
|
+
* @param oldShares Tracked receipt balance before the sync.
|
|
147
|
+
* @param newShares Tracked receipt balance after the sync.
|
|
148
|
+
*/
|
|
149
|
+
event ReceiptSynced(address indexed resource, uint256 oldShares, uint256 newShares);
|
|
150
|
+
|
|
141
151
|
// -------------------------------- Errors ----------------------------------
|
|
142
152
|
|
|
143
153
|
/// @notice Caller of an `onlyHub` function was not the registered Hub.
|
|
@@ -188,9 +198,10 @@ interface IYieldGroupBase {
|
|
|
188
198
|
error ResourceNotRegistered(address resource);
|
|
189
199
|
|
|
190
200
|
/**
|
|
191
|
-
* @notice `removeResource()` called while the
|
|
201
|
+
* @notice `removeResource()` called while the YieldGroup still accounts for receipts of the
|
|
202
|
+
* resource (the tracked ledger for a tracking family, the wallet balance otherwise).
|
|
192
203
|
* @param resource Resource attempted to be removed.
|
|
193
|
-
* @param balance
|
|
204
|
+
* @param balance Accounted receipt balance preventing removal, in the resource's share units.
|
|
194
205
|
*/
|
|
195
206
|
error ResourceHasBalance(address resource, uint256 balance);
|
|
196
207
|
|
|
@@ -246,8 +257,8 @@ interface IYieldGroupBase {
|
|
|
246
257
|
error InvalidQueue();
|
|
247
258
|
|
|
248
259
|
/**
|
|
249
|
-
* @notice Withdraw queue omits a resource
|
|
250
|
-
* then not visit.
|
|
260
|
+
* @notice Withdraw queue omits a resource whose accounted receipts are non-zero (the tracked
|
|
261
|
+
* ledger for a tracking family, the wallet otherwise), which the cascade would then not visit.
|
|
251
262
|
* @param resource The funded resource missing from the queue.
|
|
252
263
|
*/
|
|
253
264
|
error WithdrawQueueOmitsFundedResource(address resource);
|
|
@@ -266,6 +277,10 @@ interface IYieldGroupBase {
|
|
|
266
277
|
/// `totalAssets` and must never be sweepable.
|
|
267
278
|
error SweepProtectedAsset();
|
|
268
279
|
|
|
280
|
+
/// @notice `syncReceipt` was called on a family that values positions by holder, not by tracked
|
|
281
|
+
/// receipts (Centrifuge), where the sync would write a slot nothing reads.
|
|
282
|
+
error ReceiptTrackingOff();
|
|
283
|
+
|
|
269
284
|
/**
|
|
270
285
|
* @notice `sweep()` targeted a registered resource. In every family the resource address is the
|
|
271
286
|
* receipt token backing `totalAssets`, so sweeping it would drain the YieldGroup.
|
|
@@ -361,7 +376,9 @@ interface IYieldGroupBase {
|
|
|
361
376
|
function addResource(address resource, address adapter) external;
|
|
362
377
|
|
|
363
378
|
/**
|
|
364
|
-
* @notice Remove a registered resource. Requires
|
|
379
|
+
* @notice Remove a registered resource. Requires the YieldGroup to account for no receipts of it:
|
|
380
|
+
* the tracked ledger for a tracking family, the wallet balance otherwise. Receipts that
|
|
381
|
+
* arrived outside the deposit path do not block removal and are sweepable afterwards.
|
|
365
382
|
* @dev ACM role `"removeResource(address)"` (VIP). Also removes the resource from both
|
|
366
383
|
* inner queues via swap-and-pop. Emits {ResourceRemoved}.
|
|
367
384
|
* @param resource Resource to remove.
|
|
@@ -433,6 +450,27 @@ interface IYieldGroupBase {
|
|
|
433
450
|
*/
|
|
434
451
|
function sweep(address token, address to) external;
|
|
435
452
|
|
|
453
|
+
/**
|
|
454
|
+
* @notice Set the tracked receipt balance of `resource` to what it holds, adding at most
|
|
455
|
+
* `maxAdded`. This admits receipt tokens that arrived outside the deposit path (a
|
|
456
|
+
* donation, a mistransfer) into the Hub's share price; until then they sit on the
|
|
457
|
+
* YieldGroup uncounted.
|
|
458
|
+
* @dev ACM role `"syncReceipt(address,uint256)"` (VIP). Emits {ReceiptSynced}. Reverts
|
|
459
|
+
* {ReceiptTrackingOff} on a family that does not track receipts.
|
|
460
|
+
*
|
|
461
|
+
* `maxAdded` caps the sync at the amount governance reviewed. A VIP executes days after it
|
|
462
|
+
* is proposed, and anything sent in meanwhile, including over-priced receipts from a market
|
|
463
|
+
* carrying bad debt, stays uncounted above the cap. It is a cap rather than an exact match,
|
|
464
|
+
* so a single extra wei sent in before execution cannot make the sync revert.
|
|
465
|
+
*
|
|
466
|
+
* `type(uint256).max` syncs the whole wallet. The upgrade that introduced tracking needs it:
|
|
467
|
+
* every tracked balance starts at 0 there, and the wallet at execution cannot be known when
|
|
468
|
+
* the VIP is proposed. The old code already priced the whole wallet, so it admits nothing new.
|
|
469
|
+
* @param resource Registered resource to sync.
|
|
470
|
+
* @param maxAdded Most receipts this sync may add to the tracked balance.
|
|
471
|
+
*/
|
|
472
|
+
function syncReceipt(address resource, uint256 maxAdded) external;
|
|
473
|
+
|
|
436
474
|
// ---------------------------------- Views --------------------------------
|
|
437
475
|
|
|
438
476
|
/**
|
|
@@ -442,9 +480,11 @@ interface IYieldGroupBase {
|
|
|
442
480
|
function asset() external view returns (address underlying);
|
|
443
481
|
|
|
444
482
|
/**
|
|
445
|
-
* @notice
|
|
483
|
+
* @notice Underlying value of the receipts this YieldGroup accounts for across its resources,
|
|
484
|
+
* plus its idle `asset` balance. A tracking family prices only the receipts its own
|
|
485
|
+
* deposits minted; Centrifuge prices its whole wallet.
|
|
446
486
|
* @dev Hub sums `totalAssets()` over its registered YieldGroups to compute its own totalAssets().
|
|
447
|
-
* @return total Asset units
|
|
487
|
+
* @return total Asset units the YieldGroup accounts for.
|
|
448
488
|
*/
|
|
449
489
|
function totalAssets() external view returns (uint256 total);
|
|
450
490
|
|
|
@@ -502,6 +542,15 @@ interface IYieldGroupBase {
|
|
|
502
542
|
*/
|
|
503
543
|
function resourceConfig(address resource) external view returns (bool registered, bool paused, address adapter);
|
|
504
544
|
|
|
545
|
+
/**
|
|
546
|
+
* @notice Receipt tokens of `resource` that count toward `totalAssets()`: those this YieldGroup
|
|
547
|
+
* minted through its own deposits, net of what it redeemed. Always 0 for a family that
|
|
548
|
+
* does not track receipts (Centrifuge), which prices its wallet instead.
|
|
549
|
+
* @param resource Resource to look up.
|
|
550
|
+
* @return shares Tracked receipt balance, in the resource's own share units.
|
|
551
|
+
*/
|
|
552
|
+
function trackedReceipt(address resource) external view returns (uint256 shares);
|
|
553
|
+
|
|
505
554
|
/// @notice Current inner deposit-routing order.
|
|
506
555
|
/// @return queue Storage copy of the inner deposit queue.
|
|
507
556
|
function innerDepositQueue() external view returns (address[] memory queue);
|
|
@@ -104,6 +104,15 @@ interface IVToken {
|
|
|
104
104
|
*/
|
|
105
105
|
function getCash() external view returns (uint256 cash);
|
|
106
106
|
|
|
107
|
+
/**
|
|
108
|
+
* @notice Protocol reserves held inside `getCash()`.
|
|
109
|
+
* @dev `accrueInterest` sends them out of cash to the ProtocolShareReserve once
|
|
110
|
+
* `reduceReservesBlockDelta` blocks have elapsed, so a redeem can only count on
|
|
111
|
+
* `getCash() - totalReserves()`.
|
|
112
|
+
* @return reserves Underlying units reserved for the protocol.
|
|
113
|
+
*/
|
|
114
|
+
function totalReserves() external view returns (uint256 reserves);
|
|
115
|
+
|
|
107
116
|
/**
|
|
108
117
|
* @notice The ERC-20 underlying token. Reverts for vBNB (which has no `underlying`
|
|
109
118
|
* accessor); the Core Yield Group v1 uses this revert as a guard against vBNB
|
|
@@ -6,6 +6,7 @@ import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.s
|
|
|
6
6
|
import { ReentrancyGuard } from "@openzeppelin/contracts/security/ReentrancyGuard.sol";
|
|
7
7
|
|
|
8
8
|
import { IHub } from "../interfaces/IHub.sol";
|
|
9
|
+
import { IHubRegistry } from "../interfaces/IHubRegistry.sol";
|
|
9
10
|
import { IMigrator } from "../interfaces/IMigrator.sol";
|
|
10
11
|
import { IVBep20 } from "../interfaces/external/IVBep20.sol";
|
|
11
12
|
import { IWBNB } from "../interfaces/external/IWBNB.sol";
|
|
@@ -14,12 +15,16 @@ import { IWBNB } from "../interfaces/external/IWBNB.sol";
|
|
|
14
15
|
* @title Migrator
|
|
15
16
|
* @author Venus
|
|
16
17
|
* @notice One-click migration from a Venus Core position into a Liquidity Hub. A single immutable,
|
|
17
|
-
* permissionless deployment serves every Hub; the target Hub is supplied per call
|
|
18
|
+
* permissionless deployment serves every registered Hub; the target Hub is supplied per call
|
|
19
|
+
* and must be present in the HubRegistry.
|
|
18
20
|
* @dev Stateless by design — no proxy, no admin, no funds held between calls. Each migration is
|
|
19
21
|
* atomic: pull the user's vToken, redeem it to the underlying, deposit that into the Hub, and
|
|
20
22
|
* mint shares straight to the receiver. If any leg fails the whole call reverts and the user
|
|
21
23
|
* keeps their vToken.
|
|
22
24
|
*
|
|
25
|
+
* The target `hub` is checked against the immutable {HUB_REGISTRY} before any funds move, so a
|
|
26
|
+
* migration can only land in a Hub governance has registered.
|
|
27
|
+
*
|
|
23
28
|
* Accounting is done by balance delta, never by a self-reported amount: Core `redeem` returns
|
|
24
29
|
* a Compound error code (not the redeemed amount) and silently nets out any Comptroller
|
|
25
30
|
* treasury fee, so the Migrator measures what actually arrived and deposits exactly that. The
|
|
@@ -34,16 +39,24 @@ import { IWBNB } from "../interfaces/external/IWBNB.sol";
|
|
|
34
39
|
contract Migrator is IMigrator, ReentrancyGuard {
|
|
35
40
|
using SafeERC20 for IERC20;
|
|
36
41
|
|
|
37
|
-
/// @notice
|
|
42
|
+
/// @notice Governance-curated directory of valid Hubs.
|
|
43
|
+
IHubRegistry public immutable HUB_REGISTRY;
|
|
44
|
+
/// @notice Canonical wrapped-native token (WBNB).
|
|
38
45
|
IWBNB public immutable WBNB;
|
|
39
|
-
/// @notice Canonical Venus native market (vBNB)
|
|
46
|
+
/// @notice Canonical Venus native market (vBNB).
|
|
40
47
|
IVBep20 public immutable VBNB;
|
|
41
48
|
|
|
42
49
|
/**
|
|
43
|
-
* @param wbnb_ Wrapped-native token
|
|
44
|
-
* @param vbnb_ Venus native market (vBNB)
|
|
50
|
+
* @param wbnb_ Wrapped-native token (WBNB). Mandatory; the constructor reverts on the zero address.
|
|
51
|
+
* @param vbnb_ Venus native market (vBNB). Mandatory; the constructor reverts on the zero address.
|
|
52
|
+
* @param hubRegistry_ The HubRegistry every migration target is validated against. Mandatory;
|
|
53
|
+
* the constructor reverts on the zero address, since without it no Hub would be accepted.
|
|
45
54
|
*/
|
|
46
|
-
constructor(IWBNB wbnb_, IVBep20 vbnb_) {
|
|
55
|
+
constructor(IWBNB wbnb_, IVBep20 vbnb_, IHubRegistry hubRegistry_) {
|
|
56
|
+
if (address(wbnb_) == address(0) || address(vbnb_) == address(0) || address(hubRegistry_) == address(0)) {
|
|
57
|
+
revert ZeroAddress();
|
|
58
|
+
}
|
|
59
|
+
HUB_REGISTRY = hubRegistry_;
|
|
47
60
|
WBNB = wbnb_;
|
|
48
61
|
VBNB = vbnb_;
|
|
49
62
|
}
|
|
@@ -111,6 +124,7 @@ contract Migrator is IMigrator, ReentrancyGuard {
|
|
|
111
124
|
revert ZeroAddress();
|
|
112
125
|
}
|
|
113
126
|
if (vTokenAmount == 0) revert ZeroAmount();
|
|
127
|
+
if (!HUB_REGISTRY.isHub(hub)) revert HubNotRegistered(hub);
|
|
114
128
|
|
|
115
129
|
address asset = IHub(hub).asset();
|
|
116
130
|
address vTokenUnderlying = IVBep20(vToken).underlying();
|
|
@@ -135,11 +149,9 @@ contract Migrator is IMigrator, ReentrancyGuard {
|
|
|
135
149
|
private
|
|
136
150
|
returns (uint256 shares)
|
|
137
151
|
{
|
|
138
|
-
if (address(WBNB) == address(0) || address(VBNB) == address(0)) {
|
|
139
|
-
revert BNBMigrationUnsupported();
|
|
140
|
-
}
|
|
141
152
|
if (hub == address(0) || receiver == address(0)) revert ZeroAddress();
|
|
142
153
|
if (vBNBAmount == 0) revert ZeroAmount();
|
|
154
|
+
if (!HUB_REGISTRY.isHub(hub)) revert HubNotRegistered(hub);
|
|
143
155
|
|
|
144
156
|
address asset = IHub(hub).asset();
|
|
145
157
|
if (asset != address(WBNB)) revert AssetMismatch(address(WBNB), asset);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"address": "
|
|
3
|
-
"block":
|
|
2
|
+
"address": "0x0f62927d18Fd35712622C2c6C3F730EB8a18b71B",
|
|
3
|
+
"block": 132740470,
|
|
4
4
|
"chainId": 56,
|
|
5
5
|
"contract": "AdapterCoreV1",
|
|
6
6
|
"abi": [
|
|
@@ -158,6 +158,30 @@
|
|
|
158
158
|
],
|
|
159
159
|
"stateMutability": "view"
|
|
160
160
|
},
|
|
161
|
+
{
|
|
162
|
+
"type": "function",
|
|
163
|
+
"name": "receiptValue",
|
|
164
|
+
"inputs": [
|
|
165
|
+
{
|
|
166
|
+
"name": "resource",
|
|
167
|
+
"type": "address",
|
|
168
|
+
"internalType": "address"
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
"name": "vBal",
|
|
172
|
+
"type": "uint256",
|
|
173
|
+
"internalType": "uint256"
|
|
174
|
+
}
|
|
175
|
+
],
|
|
176
|
+
"outputs": [
|
|
177
|
+
{
|
|
178
|
+
"name": "",
|
|
179
|
+
"type": "uint256",
|
|
180
|
+
"internalType": "uint256"
|
|
181
|
+
}
|
|
182
|
+
],
|
|
183
|
+
"stateMutability": "view"
|
|
184
|
+
},
|
|
161
185
|
{
|
|
162
186
|
"type": "function",
|
|
163
187
|
"name": "resourceName",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"address": "
|
|
3
|
-
"block":
|
|
2
|
+
"address": "0x40fDc0fef94D607EE4341230afb09bcDB0B949E2",
|
|
3
|
+
"block": 132740470,
|
|
4
4
|
"chainId": 56,
|
|
5
5
|
"contract": "AdapterFRV",
|
|
6
6
|
"abi": [
|
|
@@ -132,6 +132,30 @@
|
|
|
132
132
|
],
|
|
133
133
|
"stateMutability": "view"
|
|
134
134
|
},
|
|
135
|
+
{
|
|
136
|
+
"type": "function",
|
|
137
|
+
"name": "receiptValue",
|
|
138
|
+
"inputs": [
|
|
139
|
+
{
|
|
140
|
+
"name": "resource",
|
|
141
|
+
"type": "address",
|
|
142
|
+
"internalType": "address"
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
"name": "shares",
|
|
146
|
+
"type": "uint256",
|
|
147
|
+
"internalType": "uint256"
|
|
148
|
+
}
|
|
149
|
+
],
|
|
150
|
+
"outputs": [
|
|
151
|
+
{
|
|
152
|
+
"name": "",
|
|
153
|
+
"type": "uint256",
|
|
154
|
+
"internalType": "uint256"
|
|
155
|
+
}
|
|
156
|
+
],
|
|
157
|
+
"stateMutability": "view"
|
|
158
|
+
},
|
|
135
159
|
{
|
|
136
160
|
"type": "function",
|
|
137
161
|
"name": "resourceName",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"address": "
|
|
3
|
-
"block":
|
|
2
|
+
"address": "0x4Afb747ce8dDef689d5484FFdfB69Ac8bC7cAc8B",
|
|
3
|
+
"block": 132740470,
|
|
4
4
|
"chainId": 56,
|
|
5
5
|
"contract": "AdapterFlux",
|
|
6
6
|
"abi": [
|
|
@@ -151,6 +151,30 @@
|
|
|
151
151
|
],
|
|
152
152
|
"stateMutability": "view"
|
|
153
153
|
},
|
|
154
|
+
{
|
|
155
|
+
"type": "function",
|
|
156
|
+
"name": "receiptValue",
|
|
157
|
+
"inputs": [
|
|
158
|
+
{
|
|
159
|
+
"name": "resource",
|
|
160
|
+
"type": "address",
|
|
161
|
+
"internalType": "address"
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
"name": "shares",
|
|
165
|
+
"type": "uint256",
|
|
166
|
+
"internalType": "uint256"
|
|
167
|
+
}
|
|
168
|
+
],
|
|
169
|
+
"outputs": [
|
|
170
|
+
{
|
|
171
|
+
"name": "",
|
|
172
|
+
"type": "uint256",
|
|
173
|
+
"internalType": "uint256"
|
|
174
|
+
}
|
|
175
|
+
],
|
|
176
|
+
"stateMutability": "view"
|
|
177
|
+
},
|
|
154
178
|
{
|
|
155
179
|
"type": "function",
|
|
156
180
|
"name": "resourceName",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"address": "
|
|
3
|
-
"block":
|
|
2
|
+
"address": "0xD08596E58325724C824100bA87f2470493Fe342d",
|
|
3
|
+
"block": 132740470,
|
|
4
4
|
"chainId": 56,
|
|
5
5
|
"contract": "AdapterSpokeV1",
|
|
6
6
|
"abi": [
|
|
@@ -158,6 +158,30 @@
|
|
|
158
158
|
],
|
|
159
159
|
"stateMutability": "view"
|
|
160
160
|
},
|
|
161
|
+
{
|
|
162
|
+
"type": "function",
|
|
163
|
+
"name": "receiptValue",
|
|
164
|
+
"inputs": [
|
|
165
|
+
{
|
|
166
|
+
"name": "resource",
|
|
167
|
+
"type": "address",
|
|
168
|
+
"internalType": "address"
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
"name": "vBal",
|
|
172
|
+
"type": "uint256",
|
|
173
|
+
"internalType": "uint256"
|
|
174
|
+
}
|
|
175
|
+
],
|
|
176
|
+
"outputs": [
|
|
177
|
+
{
|
|
178
|
+
"name": "",
|
|
179
|
+
"type": "uint256",
|
|
180
|
+
"internalType": "uint256"
|
|
181
|
+
}
|
|
182
|
+
],
|
|
183
|
+
"stateMutability": "view"
|
|
184
|
+
},
|
|
161
185
|
{
|
|
162
186
|
"type": "function",
|
|
163
187
|
"name": "resourceName",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"address": "
|
|
3
|
-
"block":
|
|
2
|
+
"address": "0xb0D77DC86d4E6a8282eECF3d4d456B3b94F2a7aD",
|
|
3
|
+
"block": 115268335,
|
|
4
4
|
"chainId": 56,
|
|
5
5
|
"contract": "Migrator",
|
|
6
6
|
"abi": [
|
|
@@ -16,6 +16,11 @@
|
|
|
16
16
|
"name": "vbnb_",
|
|
17
17
|
"type": "address",
|
|
18
18
|
"internalType": "contract IVBep20"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"name": "hubRegistry_",
|
|
22
|
+
"type": "address",
|
|
23
|
+
"internalType": "contract IHubRegistry"
|
|
19
24
|
}
|
|
20
25
|
],
|
|
21
26
|
"stateMutability": "nonpayable"
|
|
@@ -24,6 +29,19 @@
|
|
|
24
29
|
"type": "receive",
|
|
25
30
|
"stateMutability": "payable"
|
|
26
31
|
},
|
|
32
|
+
{
|
|
33
|
+
"type": "function",
|
|
34
|
+
"name": "HUB_REGISTRY",
|
|
35
|
+
"inputs": [],
|
|
36
|
+
"outputs": [
|
|
37
|
+
{
|
|
38
|
+
"name": "",
|
|
39
|
+
"type": "address",
|
|
40
|
+
"internalType": "contract IHubRegistry"
|
|
41
|
+
}
|
|
42
|
+
],
|
|
43
|
+
"stateMutability": "view"
|
|
44
|
+
},
|
|
27
45
|
{
|
|
28
46
|
"type": "function",
|
|
29
47
|
"name": "VBNB",
|
|
@@ -292,8 +310,14 @@
|
|
|
292
310
|
},
|
|
293
311
|
{
|
|
294
312
|
"type": "error",
|
|
295
|
-
"name": "
|
|
296
|
-
"inputs": [
|
|
313
|
+
"name": "HubNotRegistered",
|
|
314
|
+
"inputs": [
|
|
315
|
+
{
|
|
316
|
+
"name": "hub",
|
|
317
|
+
"type": "address",
|
|
318
|
+
"internalType": "address"
|
|
319
|
+
}
|
|
320
|
+
]
|
|
297
321
|
},
|
|
298
322
|
{
|
|
299
323
|
"type": "error",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"address": "
|
|
3
|
-
"block":
|
|
2
|
+
"address": "0xedB1c751Eb03274e9D15D0609B4593CC113fB09F",
|
|
3
|
+
"block": 132740470,
|
|
4
4
|
"chainId": 56,
|
|
5
5
|
"contract": "YieldGroup",
|
|
6
6
|
"abi": [
|
|
@@ -460,6 +460,24 @@
|
|
|
460
460
|
"outputs": [],
|
|
461
461
|
"stateMutability": "nonpayable"
|
|
462
462
|
},
|
|
463
|
+
{
|
|
464
|
+
"type": "function",
|
|
465
|
+
"name": "syncReceipt",
|
|
466
|
+
"inputs": [
|
|
467
|
+
{
|
|
468
|
+
"name": "resource",
|
|
469
|
+
"type": "address",
|
|
470
|
+
"internalType": "address"
|
|
471
|
+
},
|
|
472
|
+
{
|
|
473
|
+
"name": "maxAdded",
|
|
474
|
+
"type": "uint256",
|
|
475
|
+
"internalType": "uint256"
|
|
476
|
+
}
|
|
477
|
+
],
|
|
478
|
+
"outputs": [],
|
|
479
|
+
"stateMutability": "nonpayable"
|
|
480
|
+
},
|
|
463
481
|
{
|
|
464
482
|
"type": "function",
|
|
465
483
|
"name": "totalAssets",
|
|
@@ -473,6 +491,25 @@
|
|
|
473
491
|
],
|
|
474
492
|
"stateMutability": "view"
|
|
475
493
|
},
|
|
494
|
+
{
|
|
495
|
+
"type": "function",
|
|
496
|
+
"name": "trackedReceipt",
|
|
497
|
+
"inputs": [
|
|
498
|
+
{
|
|
499
|
+
"name": "resource",
|
|
500
|
+
"type": "address",
|
|
501
|
+
"internalType": "address"
|
|
502
|
+
}
|
|
503
|
+
],
|
|
504
|
+
"outputs": [
|
|
505
|
+
{
|
|
506
|
+
"name": "",
|
|
507
|
+
"type": "uint256",
|
|
508
|
+
"internalType": "uint256"
|
|
509
|
+
}
|
|
510
|
+
],
|
|
511
|
+
"stateMutability": "view"
|
|
512
|
+
},
|
|
476
513
|
{
|
|
477
514
|
"type": "function",
|
|
478
515
|
"name": "unpauseResource",
|
|
@@ -622,6 +659,31 @@
|
|
|
622
659
|
],
|
|
623
660
|
"anonymous": false
|
|
624
661
|
},
|
|
662
|
+
{
|
|
663
|
+
"type": "event",
|
|
664
|
+
"name": "ReceiptSynced",
|
|
665
|
+
"inputs": [
|
|
666
|
+
{
|
|
667
|
+
"name": "resource",
|
|
668
|
+
"type": "address",
|
|
669
|
+
"indexed": true,
|
|
670
|
+
"internalType": "address"
|
|
671
|
+
},
|
|
672
|
+
{
|
|
673
|
+
"name": "oldShares",
|
|
674
|
+
"type": "uint256",
|
|
675
|
+
"indexed": false,
|
|
676
|
+
"internalType": "uint256"
|
|
677
|
+
},
|
|
678
|
+
{
|
|
679
|
+
"name": "newShares",
|
|
680
|
+
"type": "uint256",
|
|
681
|
+
"indexed": false,
|
|
682
|
+
"internalType": "uint256"
|
|
683
|
+
}
|
|
684
|
+
],
|
|
685
|
+
"anonymous": false
|
|
686
|
+
},
|
|
625
687
|
{
|
|
626
688
|
"type": "event",
|
|
627
689
|
"name": "ResourceAccrualFailed",
|
|
@@ -897,6 +959,11 @@
|
|
|
897
959
|
"name": "OnlySelf",
|
|
898
960
|
"inputs": []
|
|
899
961
|
},
|
|
962
|
+
{
|
|
963
|
+
"type": "error",
|
|
964
|
+
"name": "ReceiptTrackingOff",
|
|
965
|
+
"inputs": []
|
|
966
|
+
},
|
|
900
967
|
{
|
|
901
968
|
"type": "error",
|
|
902
969
|
"name": "ResourceAlreadyRegistered",
|