@bananapus/suckers-v6 0.0.79 → 1.0.1
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/package.json +3 -3
- package/src/JBSucker.sol +25 -39
- package/src/JBSuckerRegistry.sol +3 -3
- package/src/interfaces/IJBSucker.sol +8 -5
- package/src/libraries/JBSuckerLib.sol +16 -15
- package/src/structs/JBChainAccounting.sol +13 -14
- package/src/structs/JBPeerChainContext.sol +4 -4
- package/src/structs/JBSourceContext.sol +7 -10
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bananapus/suckers-v6",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@arbitrum/nitro-contracts": "3.2.0",
|
|
30
|
-
"@bananapus/core-v6": "^0.0
|
|
31
|
-
"@bananapus/permission-ids-v6": "^0.0
|
|
30
|
+
"@bananapus/core-v6": "^1.0.0",
|
|
31
|
+
"@bananapus/permission-ids-v6": "^1.0.0",
|
|
32
32
|
"@chainlink/contracts-ccip": "1.6.4",
|
|
33
33
|
"@openzeppelin/contracts": "5.6.1",
|
|
34
34
|
"@prb/math": "4.1.2",
|
package/src/JBSucker.sol
CHANGED
|
@@ -332,12 +332,12 @@ abstract contract JBSucker is ERC2771Context, JBPermissioned, Initializable, ERC
|
|
|
332
332
|
/// project's chain count.
|
|
333
333
|
uint256[] private _peerChainIds;
|
|
334
334
|
|
|
335
|
-
/// @notice Each peer chain's
|
|
336
|
-
/// @dev Stored
|
|
337
|
-
///
|
|
338
|
-
///
|
|
339
|
-
///
|
|
340
|
-
/// @custom:param chainId The peer chain to read the
|
|
335
|
+
/// @notice Each peer chain's un-valued per-context surplus and balance from its latest accepted record.
|
|
336
|
+
/// @dev Stored in this sucker's token namespace where a remote-token mapping exists; unmapped tokens stay as
|
|
337
|
+
/// received. `peerChainContextsOf` resolves these token keys for local valuation.
|
|
338
|
+
/// A fresher record for a chain replaces that chain's set from scratch; a context dropped by the fresher record
|
|
339
|
+
/// simply vanishes.
|
|
340
|
+
/// @custom:param chainId The peer chain to read the contexts of.
|
|
341
341
|
mapping(uint256 chainId => JBSourceContext[]) private _peerContextsOf;
|
|
342
342
|
|
|
343
343
|
//*********************************************************************//
|
|
@@ -882,11 +882,11 @@ abstract contract JBSucker is ERC2771Context, JBPermissioned, Initializable, ERC
|
|
|
882
882
|
return _outboxOf[token];
|
|
883
883
|
}
|
|
884
884
|
|
|
885
|
-
/// @notice The
|
|
886
|
-
/// @dev The registry reads this to gather a project's full cross-chain knowledge and re-gossip it.
|
|
887
|
-
///
|
|
888
|
-
///
|
|
889
|
-
/// @return accounts One
|
|
885
|
+
/// @notice The un-valued accounting record this sucker holds for every peer chain it has heard about.
|
|
886
|
+
/// @dev The registry reads this to gather a project's full cross-chain knowledge and re-gossip it. Incoming
|
|
887
|
+
/// contexts are stored in this sucker's token namespace where a mapping exists, so a hub forwards sibling-chain
|
|
888
|
+
/// accounting in hub-local token terms and the next spoke only needs its mapping to the hub token.
|
|
889
|
+
/// @return accounts One accounting record per known peer chain.
|
|
890
890
|
function peerChainAccountsOf() external view returns (JBChainAccounting[] memory accounts) {
|
|
891
891
|
uint256[] storage chainIds = _peerChainIds;
|
|
892
892
|
uint256 numChains = chainIds.length;
|
|
@@ -907,10 +907,10 @@ abstract contract JBSucker is ERC2771Context, JBPermissioned, Initializable, ERC
|
|
|
907
907
|
|
|
908
908
|
/// @notice One peer chain's per-currency surplus and balance from its latest accepted record, plus that record's
|
|
909
909
|
/// freshness key.
|
|
910
|
-
/// @dev
|
|
911
|
-
/// together. The result is un-valued — the registry values each context into
|
|
912
|
-
/// consults no price oracle. Contexts that share a currency but carry different
|
|
913
|
-
/// the raw amounts are on different scales and cannot be summed directly.
|
|
910
|
+
/// @dev Stored contexts are already keyed in this sucker's token namespace where a mapping exists. This folds
|
|
911
|
+
/// same-currency, same-decimals entries together. The result is un-valued — the registry values each context into
|
|
912
|
+
/// a requested currency; the sucker consults no price oracle. Contexts that share a currency but carry different
|
|
913
|
+
/// decimals are kept separate because the raw amounts are on different scales and cannot be summed directly.
|
|
914
914
|
/// @param chainId The peer chain to read the contexts of.
|
|
915
915
|
/// @return contexts The per-currency surplus and balance for the chain.
|
|
916
916
|
/// @return snapshot The source freshness key of the chain's latest accepted record.
|
|
@@ -919,25 +919,8 @@ abstract contract JBSucker is ERC2771Context, JBPermissioned, Initializable, ERC
|
|
|
919
919
|
view
|
|
920
920
|
returns (JBPeerChainContext[] memory contexts, uint256 snapshot)
|
|
921
921
|
{
|
|
922
|
-
JBSourceContext[] storage rawContexts = _peerContextsOf[chainId];
|
|
923
|
-
uint256 numRaw = rawContexts.length;
|
|
924
|
-
|
|
925
|
-
// Copy the raw contexts to memory and resolve each source-local token to a local token (mapping first, identity
|
|
926
|
-
// fallback). The bytecode-heavy currency resolution and fold then run in the library.
|
|
927
|
-
JBSourceContext[] memory raw = new JBSourceContext[](numRaw);
|
|
928
|
-
address[] memory localTokens = new address[](numRaw);
|
|
929
|
-
for (uint256 i; i < numRaw;) {
|
|
930
|
-
JBSourceContext storage ctx = rawContexts[i];
|
|
931
|
-
raw[i] = ctx;
|
|
932
|
-
address contextToken = _localTokenForRemoteToken[ctx.token];
|
|
933
|
-
localTokens[i] = contextToken == address(0) ? _toAddress(ctx.token) : contextToken;
|
|
934
|
-
unchecked {
|
|
935
|
-
++i;
|
|
936
|
-
}
|
|
937
|
-
}
|
|
938
|
-
|
|
939
922
|
contexts = JBSuckerLib.foldPeerContexts({
|
|
940
|
-
directory: DIRECTORY, projectId: projectId(),
|
|
923
|
+
directory: DIRECTORY, projectId: projectId(), rawContexts: _peerContextsOf[chainId]
|
|
941
924
|
});
|
|
942
925
|
snapshot = snapshotTimestampOf[chainId];
|
|
943
926
|
}
|
|
@@ -1600,12 +1583,13 @@ abstract contract JBSucker is ERC2771Context, JBPermissioned, Initializable, ERC
|
|
|
1600
1583
|
/// @notice Store one source chain's accounting record if it is fresher than the one already held for that chain.
|
|
1601
1584
|
/// @dev A record for the local chain is ignored — a chain reads its own accounting directly. Each peer chain is
|
|
1602
1585
|
/// gated independently on a strictly-newer freshness key, so a stale relay cannot roll back any chain and records
|
|
1603
|
-
/// delivered out of order converge.
|
|
1604
|
-
///
|
|
1586
|
+
/// delivered out of order converge. Any source token that matches this sucker's remote-token mapping is re-keyed
|
|
1587
|
+
/// to this sucker's local token before storage, so forwarded records are already in the current hop's token
|
|
1588
|
+
/// namespace.
|
|
1605
1589
|
/// @param chainId The source chain the record describes.
|
|
1606
1590
|
/// @param sourceTimestamp The record's source-chain freshness key.
|
|
1607
1591
|
/// @param sourceTotalSupply The source chain's total project-token supply.
|
|
1608
|
-
/// @param sourceContexts The source chain's
|
|
1592
|
+
/// @param sourceContexts The source chain's per-context surplus and balance.
|
|
1609
1593
|
function _storeChainAccounting(
|
|
1610
1594
|
uint256 chainId,
|
|
1611
1595
|
uint256 sourceTimestamp,
|
|
@@ -1634,15 +1618,17 @@ abstract contract JBSucker is ERC2771Context, JBPermissioned, Initializable, ERC
|
|
|
1634
1618
|
_peerChainIds.push(chainId);
|
|
1635
1619
|
}
|
|
1636
1620
|
|
|
1637
|
-
// Rebuild this chain's
|
|
1638
|
-
// Each context
|
|
1639
|
-
//
|
|
1621
|
+
// Rebuild this chain's context set from scratch. A context dropped by the fresher record is simply absent.
|
|
1622
|
+
// Each context keeps its source amount and decimals, while its token key is localized for this hop when a
|
|
1623
|
+
// mapping exists.
|
|
1640
1624
|
delete _peerContextsOf[chainId];
|
|
1641
1625
|
JBSourceContext[] storage storedContexts = _peerContextsOf[chainId];
|
|
1642
1626
|
|
|
1643
1627
|
uint256 numContexts = sourceContexts.length;
|
|
1644
1628
|
for (uint256 i; i < numContexts;) {
|
|
1645
1629
|
storedContexts.push(sourceContexts[i]);
|
|
1630
|
+
address localToken = _localTokenForRemoteToken[sourceContexts[i].token];
|
|
1631
|
+
if (localToken != address(0)) storedContexts[i].token = bytes32(uint256(uint160(localToken)));
|
|
1646
1632
|
unchecked {
|
|
1647
1633
|
++i;
|
|
1648
1634
|
}
|
package/src/JBSuckerRegistry.sol
CHANGED
|
@@ -610,7 +610,7 @@ contract JBSuckerRegistry is ERC2771Context, Ownable, JBPermissioned, IJBSuckerR
|
|
|
610
610
|
return ERC2771Context._contextSuffixLength();
|
|
611
611
|
}
|
|
612
612
|
|
|
613
|
-
/// @notice Reads one sucker's
|
|
613
|
+
/// @notice Reads one sucker's locally-keyed records and folds each into the per-chain gather scratch.
|
|
614
614
|
/// @dev Extracted from `peerChainAccountsOf` to keep its stack shallow. A sucker that reverts contributes nothing.
|
|
615
615
|
/// The destination chain, the local chain, and chain 0 are excluded.
|
|
616
616
|
/// @param scratch The per-chain gather scratch to fold records into.
|
|
@@ -706,8 +706,8 @@ contract JBSuckerRegistry is ERC2771Context, Ownable, JBPermissioned, IJBSuckerR
|
|
|
706
706
|
scratch.hasActiveValue = new bool[](len);
|
|
707
707
|
}
|
|
708
708
|
|
|
709
|
-
/// @notice Records one source chain's
|
|
710
|
-
/// @dev Mirrors `_recordPeerValue`'s selection rule for
|
|
709
|
+
/// @notice Records one source chain's accounting record into a per-chain gather scratch, keeping the freshest.
|
|
710
|
+
/// @dev Mirrors `_recordPeerValue`'s selection rule for gathered records: an active sucker's record supersedes a
|
|
711
711
|
/// deprecated one's for the same chain; among same-state records the strictly-fresher timestamp wins; equal
|
|
712
712
|
/// freshness keeps the first writer, since records from one origin chain at one freshness key are identical. Used
|
|
713
713
|
/// to gather records for re-gossiping.
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
2
|
pragma solidity ^0.8.0;
|
|
3
3
|
|
|
4
|
-
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
|
|
5
4
|
import {IJBDirectory} from "@bananapus/core-v6/src/interfaces/IJBDirectory.sol";
|
|
6
5
|
import {IJBProjects} from "@bananapus/core-v6/src/interfaces/IJBProjects.sol";
|
|
7
6
|
import {IJBTokens} from "@bananapus/core-v6/src/interfaces/IJBTokens.sol";
|
|
7
|
+
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
|
|
8
|
+
|
|
9
|
+
import {JBSuckerState} from "../enums/JBSuckerState.sol";
|
|
10
|
+
|
|
8
11
|
import {JBAccountingSnapshot} from "../structs/JBAccountingSnapshot.sol";
|
|
9
12
|
import {JBChainAccounting} from "../structs/JBChainAccounting.sol";
|
|
10
13
|
import {JBClaim} from "../structs/JBClaim.sol";
|
|
@@ -13,7 +16,6 @@ import {JBOutboxTree} from "../structs/JBOutboxTree.sol";
|
|
|
13
16
|
import {JBPeerChainContext} from "../structs/JBPeerChainContext.sol";
|
|
14
17
|
import {JBPeerChainValue} from "../structs/JBPeerChainValue.sol";
|
|
15
18
|
import {JBRemoteToken} from "../structs/JBRemoteToken.sol";
|
|
16
|
-
import {JBSuckerState} from "../enums/JBSuckerState.sol";
|
|
17
19
|
import {JBTokenMapping} from "../structs/JBTokenMapping.sol";
|
|
18
20
|
|
|
19
21
|
/// @notice The minimal interface for a sucker contract.
|
|
@@ -158,10 +160,11 @@ interface IJBSucker is IERC165 {
|
|
|
158
160
|
/// @return The peer address.
|
|
159
161
|
function peer() external view returns (bytes32);
|
|
160
162
|
|
|
161
|
-
/// @notice The
|
|
163
|
+
/// @notice The un-valued accounting record this sucker holds for every peer chain it has heard about.
|
|
162
164
|
/// @dev The registry reads this to gather a project's full cross-chain knowledge and re-gossip it. Records are
|
|
163
|
-
///
|
|
164
|
-
///
|
|
165
|
+
/// keyed to this sucker's local token when a source token matches a remote-token mapping. The next receiver only
|
|
166
|
+
/// needs its mapping to this peer's token.
|
|
167
|
+
/// @return accounts One accounting record per known peer chain.
|
|
165
168
|
function peerChainAccountsOf() external view returns (JBChainAccounting[] memory accounts);
|
|
166
169
|
|
|
167
170
|
/// @notice One peer chain's per-currency surplus and balance from its latest accepted record, plus its freshness
|
|
@@ -5,22 +5,24 @@ import {IJBController} from "@bananapus/core-v6/src/interfaces/IJBController.sol
|
|
|
5
5
|
import {IJBDirectory} from "@bananapus/core-v6/src/interfaces/IJBDirectory.sol";
|
|
6
6
|
import {IJBMultiTerminal} from "@bananapus/core-v6/src/interfaces/IJBMultiTerminal.sol";
|
|
7
7
|
import {IJBTerminal} from "@bananapus/core-v6/src/interfaces/IJBTerminal.sol";
|
|
8
|
-
import {JBAccountingContext} from "@bananapus/core-v6/src/structs/JBAccountingContext.sol";
|
|
9
8
|
import {JBRulesetMetadataResolver} from "@bananapus/core-v6/src/libraries/JBRulesetMetadataResolver.sol";
|
|
9
|
+
import {JBAccountingContext} from "@bananapus/core-v6/src/structs/JBAccountingContext.sol";
|
|
10
10
|
import {JBRuleset} from "@bananapus/core-v6/src/structs/JBRuleset.sol";
|
|
11
11
|
import {JBRulesetMetadata} from "@bananapus/core-v6/src/structs/JBRulesetMetadata.sol";
|
|
12
12
|
import {IERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
|
|
13
13
|
|
|
14
14
|
import {IJBPeerChainAdjustedAccounts} from "../interfaces/IJBPeerChainAdjustedAccounts.sol";
|
|
15
15
|
import {IJBSuckerRegistry} from "../interfaces/IJBSuckerRegistry.sol";
|
|
16
|
+
|
|
16
17
|
import {JBPeerChainAdjustedAccountsLib} from "./JBPeerChainAdjustedAccountsLib.sol";
|
|
18
|
+
import {MerkleLib} from "../utils/MerkleLib.sol";
|
|
19
|
+
|
|
17
20
|
import {JBAccountingSnapshot} from "../structs/JBAccountingSnapshot.sol";
|
|
18
21
|
import {JBChainAccounting} from "../structs/JBChainAccounting.sol";
|
|
19
22
|
import {JBInboxTreeRoot} from "../structs/JBInboxTreeRoot.sol";
|
|
20
23
|
import {JBMessageRoot} from "../structs/JBMessageRoot.sol";
|
|
21
24
|
import {JBPeerChainContext} from "../structs/JBPeerChainContext.sol";
|
|
22
25
|
import {JBSourceContext} from "../structs/JBSourceContext.sol";
|
|
23
|
-
import {MerkleLib} from "../utils/MerkleLib.sol";
|
|
24
26
|
|
|
25
27
|
/// @notice Library with bytecode-heavy functions extracted from JBSucker to reduce child contract sizes.
|
|
26
28
|
/// @dev These are `external` library functions, so they are deployed as a separate contract and called via
|
|
@@ -186,23 +188,20 @@ library JBSuckerLib {
|
|
|
186
188
|
}
|
|
187
189
|
}
|
|
188
190
|
|
|
189
|
-
/// @notice Folds a peer chain's
|
|
190
|
-
/// local currency.
|
|
191
|
+
/// @notice Folds a peer chain's source contexts into per-currency surplus and balance.
|
|
191
192
|
/// @dev Extracted from `JBSucker.peerChainContextsOf` to reduce child contract bytecode. Called via DELEGATECALL.
|
|
192
|
-
///
|
|
193
|
-
///
|
|
194
|
-
///
|
|
195
|
-
///
|
|
196
|
-
///
|
|
193
|
+
/// The caller stores mapped remote-token keys in its local token namespace before this runs. This derives each
|
|
194
|
+
/// token's authoritative accounting-context currency and merges entries that share BOTH currency AND decimals. The
|
|
195
|
+
/// accounting-context currency is immutable, so re-resolving on each read is safe. Entries that share a currency
|
|
196
|
+
/// but carry different decimals stay separate, since the raw amounts are on different scales. No price oracle is
|
|
197
|
+
/// consulted.
|
|
197
198
|
/// @param directory The JB directory to look up the project's terminals.
|
|
198
199
|
/// @param projectId The project whose accounting contexts to read.
|
|
199
|
-
/// @param
|
|
200
|
-
/// @param rawContexts The peer chain's raw per-context surplus and balance.
|
|
200
|
+
/// @param rawContexts The peer chain's per-context surplus and balance.
|
|
201
201
|
/// @return contexts The per-currency surplus and balance for the chain.
|
|
202
202
|
function foldPeerContexts(
|
|
203
203
|
IJBDirectory directory,
|
|
204
204
|
uint256 projectId,
|
|
205
|
-
address[] memory localTokens,
|
|
206
205
|
JBSourceContext[] memory rawContexts
|
|
207
206
|
)
|
|
208
207
|
external
|
|
@@ -219,7 +218,8 @@ library JBSuckerLib {
|
|
|
219
218
|
uint8 ctxDecimals = rawContexts[i].decimals;
|
|
220
219
|
uint128 ctxSurplus = rawContexts[i].surplus;
|
|
221
220
|
uint128 ctxBalance = rawContexts[i].balance;
|
|
222
|
-
|
|
221
|
+
address token = address(uint160(uint256(rawContexts[i].token)));
|
|
222
|
+
uint32 ctxCurrency = _currencyOf({directory: directory, projectId: projectId, token: token});
|
|
223
223
|
|
|
224
224
|
// Fold into an existing entry that matches on BOTH currency AND decimals, or append a new one.
|
|
225
225
|
bool merged;
|
|
@@ -265,7 +265,8 @@ library JBSuckerLib {
|
|
|
265
265
|
/// peer records are gathered from the registry, which is the only contract that sees a hub chain's per-peer
|
|
266
266
|
/// suckers together; it dedups them to the freshest per chain. A reverting or unset registry yields a local-only
|
|
267
267
|
/// bundle, so a standalone sucker still propagates its own record. Forwarded peer records keep their own origin
|
|
268
|
-
/// chain and freshness key
|
|
268
|
+
/// chain and freshness key, while their context token keys are already localized by the sucker they were gathered
|
|
269
|
+
/// from so the receiver only needs its mapping to the direct peer's token.
|
|
269
270
|
/// @param directory The JB directory to look up controllers and terminals.
|
|
270
271
|
/// @param registry The sucker registry that aggregates the project's per-chain records.
|
|
271
272
|
/// @param projectId The project to snapshot.
|
|
@@ -297,7 +298,7 @@ library JBSuckerLib {
|
|
|
297
298
|
peers = gathered;
|
|
298
299
|
} catch {}
|
|
299
300
|
|
|
300
|
-
// The local record leads; forwarded peer records follow
|
|
301
|
+
// The local record leads; forwarded peer records follow, keeping their own origin chain and freshness.
|
|
301
302
|
accounts = new JBChainAccounting[](peers.length + 1);
|
|
302
303
|
accounts[0] = JBChainAccounting({
|
|
303
304
|
chainId: block.chainid, totalSupply: localTotalSupply, contexts: localContexts, timestamp: sourceTimestamp
|
|
@@ -4,24 +4,23 @@ pragma solidity ^0.8.0;
|
|
|
4
4
|
import {JBSourceContext} from "./JBSourceContext.sol";
|
|
5
5
|
|
|
6
6
|
/// @notice One source chain's project-wide accounting, carried as a record in a cross-chain gossip bundle.
|
|
7
|
-
/// @dev A sucker sends its own chain's record alongside every peer-chain record it already holds
|
|
8
|
-
///
|
|
9
|
-
/// project's accounting propagates across a hub-and-spoke sucker mesh
|
|
10
|
-
///
|
|
11
|
-
///
|
|
12
|
-
///
|
|
13
|
-
///
|
|
14
|
-
/// project's same-address sucker invariant — the same CREATE2
|
|
15
|
-
/// relies on — and a peer running adversarial bytecode could
|
|
16
|
-
/// gate bounds rollback, not authorship; the supply view it feeds
|
|
17
|
-
/// surplus, so a forged record cannot by itself over-credit a cash out.
|
|
7
|
+
/// @dev A sucker sends its own chain's record alongside every peer-chain record it already holds. Each record is
|
|
8
|
+
/// stamped with its originating chain's freshness key. The receiving chain stores the freshest record per source chain,
|
|
9
|
+
/// so a project's accounting propagates across a hub-and-spoke sucker mesh without a direct sucker between every pair
|
|
10
|
+
/// of chains. `contexts` are un-valued token-denominated amounts. A direct sender's own record carries source-chain
|
|
11
|
+
/// token addresses. Forwarded peer records use the forwarding hub's local same-asset token when a mapping exists, so
|
|
12
|
+
/// the next receiver only needs a mapping to that hub token. Trust is transitive across the mesh: a receiver
|
|
13
|
+
/// authenticates only the directly-bridged peer that delivers a bundle, not the origin of each forwarded record. A
|
|
14
|
+
/// record is therefore only as trustworthy as the project's same-address sucker invariant — the same CREATE2
|
|
15
|
+
/// same-bytecode assumption every paired sucker already relies on — and a peer running adversarial bytecode could
|
|
16
|
+
/// forge another chain's record. The freshest-per-chain gate bounds rollback, not authorship; the supply view it feeds
|
|
17
|
+
/// is clamped downstream by each chain's own local surplus, so a forged record cannot by itself over-credit a cash out.
|
|
18
18
|
/// @custom:member chainId The source chain this record describes. A receiver ignores a record for its own chain, since
|
|
19
19
|
/// it reads its own local accounting directly.
|
|
20
20
|
/// @custom:member totalSupply The total token supply (including reserved tokens) on the source chain when the record
|
|
21
21
|
/// was taken. Used by the receiving chain to track cross-chain supply for cash out tax calculations.
|
|
22
|
-
/// @custom:member contexts The source chain's surplus and balance per accounting context, each in
|
|
23
|
-
///
|
|
24
|
-
/// at par.
|
|
22
|
+
/// @custom:member contexts The source chain's surplus and balance per accounting context, each in its own decimals and
|
|
23
|
+
/// un-valued. The token key may be the source token for direct records or a forwarding hub's local same-asset token.
|
|
25
24
|
/// @custom:member timestamp A monotonic source-chain freshness key for the record. The receiver keeps the freshest
|
|
26
25
|
/// record per source chain, so stale relays cannot roll back surplus, balance, or supply.
|
|
27
26
|
struct JBChainAccounting {
|
|
@@ -3,10 +3,10 @@ pragma solidity ^0.8.0;
|
|
|
3
3
|
|
|
4
4
|
/// @notice A remote chain's surplus and balance for one local currency, as last received.
|
|
5
5
|
/// @dev One entry per local currency in the latest snapshot. The local currency is the project's authoritative
|
|
6
|
-
/// accounting-context currency for the token
|
|
7
|
-
///
|
|
8
|
-
///
|
|
9
|
-
///
|
|
6
|
+
/// accounting-context currency for the stored token key. A receiver stores mapped remote-token keys under its local
|
|
7
|
+
/// same-asset token before this view is built. `surplus`/`balance` are raw, un-valued amounts in that currency's own
|
|
8
|
+
/// units; a read values them into a requested currency via the prices contract, exactly as the terminal store values
|
|
9
|
+
/// local surplus (an identity short-circuit means same-currency reads are taken at par).
|
|
10
10
|
/// @custom:member currency The local currency this context resolves to.
|
|
11
11
|
/// @custom:member decimals The context's native decimal precision, used to rescale to a requested precision.
|
|
12
12
|
/// @custom:member surplus The raw surplus held in this currency on the peer chain.
|
|
@@ -1,17 +1,14 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
2
|
pragma solidity ^0.8.0;
|
|
3
3
|
|
|
4
|
-
/// @notice One source-chain accounting context, carried
|
|
4
|
+
/// @notice One source-chain accounting context, carried un-valued in a cross-chain snapshot.
|
|
5
5
|
/// @dev The source chain reports its surplus and balance per accounting context in that context's own decimals — it
|
|
6
|
-
/// performs no price-feed valuation.
|
|
7
|
-
///
|
|
8
|
-
///
|
|
9
|
-
///
|
|
10
|
-
///
|
|
11
|
-
///
|
|
12
|
-
/// surplus.
|
|
13
|
-
/// @custom:member token The source-local token this context was read from, resolved to a local token (and thence a
|
|
14
|
-
/// local currency) on receipt. Padded to bytes32 for cross-VM compatibility.
|
|
6
|
+
/// performs no price-feed valuation. A receiver stores `token` as its own local token when a remote-token mapping
|
|
7
|
+
/// exists, or leaves the token key unchanged otherwise. Read paths derive the context's currency from that stored token
|
|
8
|
+
/// key instead of trusting a wire-carried currency, so same-asset tokens at different addresses (e.g. USDC) still fold
|
|
9
|
+
/// under the receiver's own currency. Any later valuation uses the project's normal local surplus conversions.
|
|
10
|
+
/// @custom:member token The source token key, or a receiver-local token key after a remote-token mapping has been
|
|
11
|
+
/// applied. Padded to bytes32 for cross-VM compatibility.
|
|
15
12
|
/// @custom:member decimals The context's native decimal precision (e.g. 18 for ETH, 6 for USDC).
|
|
16
13
|
/// @custom:member surplus The raw, un-valued surplus held in this context, in the context's own units. Capped to
|
|
17
14
|
/// `uint128` for cross-VM (SVM) compatibility, matching the leaf-amount cap.
|