@bananapus/suckers-v6 0.0.69 → 0.0.71
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 +1 -0
- package/package.json +2 -2
- package/src/JBSucker.sol +12 -8
- package/src/structs/JBLeaf.sol +3 -5
package/README.md
CHANGED
|
@@ -64,6 +64,7 @@ That means every bridge path has two trust surfaces:
|
|
|
64
64
|
- do not reason about suckers as if they were generic ERC-20 bridges
|
|
65
65
|
- root ordering and message delivery semantics matter as much as proof format
|
|
66
66
|
- token mapping is part of the economic invariant
|
|
67
|
+
- peer contexts are merged only when they share both currency and decimals; same-currency contexts with different decimals are kept separate and valued independently at read time, never summed across precisions
|
|
67
68
|
- emergency and deprecation paths are part of normal operational safety
|
|
68
69
|
|
|
69
70
|
## Where State Lives
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bananapus/suckers-v6",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.71",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@arbitrum/nitro-contracts": "3.2.0",
|
|
29
|
-
"@bananapus/core-v6": "^0.0.
|
|
29
|
+
"@bananapus/core-v6": "^0.0.81",
|
|
30
30
|
"@bananapus/permission-ids-v6": "^0.0.28",
|
|
31
31
|
"@chainlink/contracts-ccip": "1.6.4",
|
|
32
32
|
"@chainlink/local": "0.2.7",
|
package/src/JBSucker.sol
CHANGED
|
@@ -545,12 +545,18 @@ abstract contract JBSucker is ERC2771Context, JBPermissioned, Initializable, ERC
|
|
|
545
545
|
_cachedCurrencyOf[contextToken] = contextCurrency;
|
|
546
546
|
}
|
|
547
547
|
|
|
548
|
-
// Accumulate into an existing
|
|
549
|
-
//
|
|
548
|
+
// Accumulate into an existing entry that matches on BOTH currency AND decimals, or append a new one.
|
|
549
|
+
// The decimals must match: `surplus`/`balance` are raw, un-valued token amounts, so two contexts that
|
|
550
|
+
// share a currency but carry different decimals (e.g. a 6-decimal and an 18-decimal representation of
|
|
551
|
+
// the same currency) are on different scales and CANNOT be summed directly — doing so would corrupt
|
|
552
|
+
// the
|
|
553
|
+
// aggregate. Keeping them as separate entries lets the read side (`remoteSurplusOf` -> `_valued`)
|
|
554
|
+
// decimal-adjust each one independently before summing. The context set is small (one entry per
|
|
555
|
+
// distinct local currency+decimals), so a linear scan is cheaper than a mapping.
|
|
550
556
|
uint256 numStored = _peerContexts.length;
|
|
551
557
|
bool merged;
|
|
552
558
|
for (uint256 j; j < numStored;) {
|
|
553
|
-
if (_peerContexts[j].currency == contextCurrency) {
|
|
559
|
+
if (_peerContexts[j].currency == contextCurrency && _peerContexts[j].decimals == ctx.decimals) {
|
|
554
560
|
_peerContexts[j].surplus = _saturatingAddU128(_peerContexts[j].surplus, ctx.surplus);
|
|
555
561
|
_peerContexts[j].balance = _saturatingAddU128(_peerContexts[j].balance, ctx.balance);
|
|
556
562
|
merged = true;
|
|
@@ -1293,9 +1299,8 @@ abstract contract JBSucker is ERC2771Context, JBPermissioned, Initializable, ERC
|
|
|
1293
1299
|
// Record the balance before the cash out for the sanity check.
|
|
1294
1300
|
uint256 balanceBefore = _balanceOf({token: token, addr: address(this)});
|
|
1295
1301
|
|
|
1296
|
-
// Cash out the project tokens for terminal tokens. Suckers are a transparent value-mover
|
|
1297
|
-
// accounting is the entirety of their function
|
|
1298
|
-
// so `referralProjectId: 0` is correct.
|
|
1302
|
+
// Cash out the project tokens for terminal tokens. Suckers are a transparent value-mover; the bridge
|
|
1303
|
+
// accounting is the entirety of their function.
|
|
1299
1304
|
reclaimedAmount = terminal.cashOutTokensOf({
|
|
1300
1305
|
holder: address(this),
|
|
1301
1306
|
projectId: cachedProjectId,
|
|
@@ -1303,8 +1308,7 @@ abstract contract JBSucker is ERC2771Context, JBPermissioned, Initializable, ERC
|
|
|
1303
1308
|
tokenToReclaim: token,
|
|
1304
1309
|
minTokensReclaimed: minTokensReclaimed,
|
|
1305
1310
|
beneficiary: payable(address(this)),
|
|
1306
|
-
metadata: bytes("")
|
|
1307
|
-
referralProjectId: 0
|
|
1311
|
+
metadata: bytes("")
|
|
1308
1312
|
});
|
|
1309
1313
|
|
|
1310
1314
|
// Sanity check to make sure we received the expected amount.
|
package/src/structs/JBLeaf.sol
CHANGED
|
@@ -6,11 +6,9 @@ pragma solidity ^0.8.0;
|
|
|
6
6
|
/// @custom:member beneficiary The beneficiary of the leaf.
|
|
7
7
|
/// @custom:member projectTokenCount The number of project tokens to claim.
|
|
8
8
|
/// @custom:member terminalTokenAmount The amount of terminal tokens to claim.
|
|
9
|
-
/// @custom:member metadata Opaque, caller-defined
|
|
10
|
-
///
|
|
11
|
-
///
|
|
12
|
-
/// this field — it's covered by the leaf hash, so receivers can trust the value once the merkle proof verifies.
|
|
13
|
-
/// Pass `bytes32(0)` when no attribution context is needed.
|
|
9
|
+
/// @custom:member metadata Opaque, caller-defined payload that travels with the leaf inside the merkle root. The
|
|
10
|
+
/// sucker protocol itself never inspects this field — it's covered by the leaf hash, so receivers can trust the value
|
|
11
|
+
/// once the merkle proof verifies. Pass `bytes32(0)` when no extra claim context is needed.
|
|
14
12
|
struct JBLeaf {
|
|
15
13
|
uint256 index;
|
|
16
14
|
bytes32 beneficiary;
|