@bannynet/core-v6 0.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/README.md +53 -0
- package/SKILLS.md +94 -0
- package/deployments/banny-core-v5/arbitrum/Banny721TokenUriResolver.json +1809 -0
- package/deployments/banny-core-v5/arbitrum_sepolia/Banny721TokenUriResolver.json +1795 -0
- package/deployments/banny-core-v5/base/Banny721TokenUriResolver.json +1810 -0
- package/deployments/banny-core-v5/base_sepolia/Banny721TokenUriResolver.json +1796 -0
- package/deployments/banny-core-v5/ethereum/Banny721TokenUriResolver.json +1795 -0
- package/deployments/banny-core-v5/optimism/Banny721TokenUriResolver.json +1810 -0
- package/deployments/banny-core-v5/optimism_sepolia/Banny721TokenUriResolver.json +1796 -0
- package/deployments/banny-core-v5/sepolia/Banny721TokenUriResolver.json +1795 -0
- package/foundry.toml +22 -0
- package/package.json +53 -0
- package/remappings.txt +1 -0
- package/script/1.Fix.s.sol +290 -0
- package/script/Add.Denver.s.sol +75 -0
- package/script/AirdropOutfits.s.sol +2302 -0
- package/script/Deploy.s.sol +440 -0
- package/script/Drop1.s.sol +979 -0
- package/script/MigrationContractArbitrum.sol +494 -0
- package/script/MigrationContractArbitrum1.sol +170 -0
- package/script/MigrationContractArbitrum2.sol +204 -0
- package/script/MigrationContractArbitrum3.sol +174 -0
- package/script/MigrationContractArbitrum4.sol +478 -0
- package/script/MigrationContractBase1.sol +444 -0
- package/script/MigrationContractBase2.sol +175 -0
- package/script/MigrationContractBase3.sol +309 -0
- package/script/MigrationContractBase4.sol +350 -0
- package/script/MigrationContractBase5.sol +259 -0
- package/script/MigrationContractEthereum1.sol +468 -0
- package/script/MigrationContractEthereum2.sol +306 -0
- package/script/MigrationContractEthereum3.sol +349 -0
- package/script/MigrationContractEthereum4.sol +352 -0
- package/script/MigrationContractEthereum5.sol +354 -0
- package/script/MigrationContractEthereum6.sol +270 -0
- package/script/MigrationContractEthereum7.sol +439 -0
- package/script/MigrationContractEthereum8.sol +385 -0
- package/script/MigrationContractOptimism.sol +196 -0
- package/script/helpers/BannyverseDeploymentLib.sol +73 -0
- package/script/helpers/MigrationHelper.sol +155 -0
- package/script/outfit_drop/generate-migration.js +3441 -0
- package/script/outfit_drop/raw.json +43276 -0
- package/slither-ci.config.json +10 -0
- package/sphinx.lock +521 -0
- package/src/Banny721TokenUriResolver.sol +1288 -0
- package/src/interfaces/IBanny721TokenUriResolver.sol +137 -0
- package/test/Banny721TokenUriResolver.t.sol +669 -0
- package/test/BannyAttacks.t.sol +322 -0
- package/test/DecorateFlow.t.sol +1056 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity 0.8.23;
|
|
3
|
+
|
|
4
|
+
import {Banny721TokenUriResolver} from "../../src/Banny721TokenUriResolver.sol";
|
|
5
|
+
import {JB721TiersHook} from "@bananapus/721-hook-v5/src/JB721TiersHook.sol";
|
|
6
|
+
import {IJB721TiersHookStore} from "@bananapus/721-hook-v5/src/interfaces/IJB721TiersHookStore.sol";
|
|
7
|
+
|
|
8
|
+
library MigrationHelper {
|
|
9
|
+
/// @notice Get the UPC (tier ID) from a token ID
|
|
10
|
+
function _getUPC(address hook, uint256 tokenId) internal view returns (uint256) {
|
|
11
|
+
IJB721TiersHookStore store = JB721TiersHook(hook).STORE();
|
|
12
|
+
return store.tierOfTokenId({hook: hook, tokenId: tokenId, includeResolvedUri: false}).id;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function verifyV4AssetMatch(
|
|
16
|
+
Banny721TokenUriResolver resolver,
|
|
17
|
+
Banny721TokenUriResolver v4Resolver,
|
|
18
|
+
Banny721TokenUriResolver fallbackV4Resolver,
|
|
19
|
+
address hookAddress,
|
|
20
|
+
address v4HookAddress,
|
|
21
|
+
uint256 tokenId
|
|
22
|
+
)
|
|
23
|
+
internal
|
|
24
|
+
view
|
|
25
|
+
{
|
|
26
|
+
// Get V5 asset token IDs (from V5 hook)
|
|
27
|
+
(uint256 v5BackgroundId, uint256[] memory v5OutfitIds) = resolver.assetIdsOf(hookAddress, tokenId);
|
|
28
|
+
// Get V4 asset token IDs (from V4 hook)
|
|
29
|
+
(uint256 v4BackgroundId, uint256[] memory v4OutfitIds) = v4Resolver.assetIdsOf(v4HookAddress, tokenId);
|
|
30
|
+
|
|
31
|
+
// Compare background UPCs (not token IDs, since they may differ)
|
|
32
|
+
uint256 v5BackgroundUPC = v5BackgroundId == 0 ? 0 : _getUPC(hookAddress, v5BackgroundId);
|
|
33
|
+
uint256 v4BackgroundUPC = v4BackgroundId == 0 ? 0 : _getUPC(v4HookAddress, v4BackgroundId);
|
|
34
|
+
|
|
35
|
+
bool matches = v5BackgroundUPC == v4BackgroundUPC && v5OutfitIds.length == v4OutfitIds.length;
|
|
36
|
+
|
|
37
|
+
if (matches) {
|
|
38
|
+
// Compare outfit UPCs
|
|
39
|
+
for (uint256 i = 0; i < v5OutfitIds.length; i++) {
|
|
40
|
+
uint256 v5OutfitUPC = _getUPC(hookAddress, v5OutfitIds[i]);
|
|
41
|
+
uint256 v4OutfitUPC = _getUPC(v4HookAddress, v4OutfitIds[i]);
|
|
42
|
+
if (v5OutfitUPC != v4OutfitUPC) {
|
|
43
|
+
matches = false;
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (!matches) {
|
|
50
|
+
// Try fallback resolver
|
|
51
|
+
(v4BackgroundId, v4OutfitIds) = fallbackV4Resolver.assetIdsOf(v4HookAddress, tokenId);
|
|
52
|
+
v4BackgroundUPC = v4BackgroundId == 0 ? 0 : _getUPC(v4HookAddress, v4BackgroundId);
|
|
53
|
+
|
|
54
|
+
require(
|
|
55
|
+
v5BackgroundUPC == v4BackgroundUPC && v5OutfitIds.length == v4OutfitIds.length, "V4/V5 asset mismatch"
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
for (uint256 i = 0; i < v5OutfitIds.length; i++) {
|
|
59
|
+
uint256 v5OutfitUPC = _getUPC(hookAddress, v5OutfitIds[i]);
|
|
60
|
+
uint256 v4OutfitUPC = _getUPC(v4HookAddress, v4OutfitIds[i]);
|
|
61
|
+
require(v5OutfitUPC == v4OutfitUPC, "V4/V5 asset mismatch");
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/// @notice Verify that tier balances in V5 are never greater than in V4 for all owners and tiers
|
|
67
|
+
/// @param hookAddress V5 hook address
|
|
68
|
+
/// @param v4HookAddress V4 hook address
|
|
69
|
+
/// @param v4FallbackResolverAddress V4 fallback resolver address (legacy resolver)
|
|
70
|
+
/// @param owners Array of owner addresses to check
|
|
71
|
+
/// @param tierIds Array of tier IDs to check
|
|
72
|
+
function verifyTierBalances(
|
|
73
|
+
address hookAddress,
|
|
74
|
+
address v4HookAddress,
|
|
75
|
+
address v4FallbackResolverAddress,
|
|
76
|
+
address[] memory owners,
|
|
77
|
+
uint256[] memory tierIds
|
|
78
|
+
)
|
|
79
|
+
internal
|
|
80
|
+
view
|
|
81
|
+
{
|
|
82
|
+
IJB721TiersHookStore v5Store = JB721TiersHook(hookAddress).STORE();
|
|
83
|
+
IJB721TiersHookStore v4Store = JB721TiersHook(v4HookAddress).STORE();
|
|
84
|
+
|
|
85
|
+
for (uint256 i = 0; i < owners.length; i++) {
|
|
86
|
+
address owner = owners[i];
|
|
87
|
+
|
|
88
|
+
for (uint256 j = 0; j < tierIds.length; j++) {
|
|
89
|
+
uint256 tierId = tierIds[j];
|
|
90
|
+
|
|
91
|
+
// Check if this tier is owned by the fallback resolver in V4
|
|
92
|
+
// If so, skip verification (these are now owned by rightful owners in V5)
|
|
93
|
+
uint256 v4FallbackResolverBalance =
|
|
94
|
+
v4Store.tierBalanceOf(v4HookAddress, v4FallbackResolverAddress, tierId);
|
|
95
|
+
if (v4FallbackResolverBalance > 0) {
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Get V4 and V5 tier balances for this owner and tier
|
|
100
|
+
uint256 v4Balance = v4Store.tierBalanceOf(v4HookAddress, owner, tierId);
|
|
101
|
+
uint256 v5Balance = v5Store.tierBalanceOf(hookAddress, owner, tierId);
|
|
102
|
+
|
|
103
|
+
// Require that V5 balance is never greater than V4 balance
|
|
104
|
+
require(
|
|
105
|
+
v5Balance <= v4Balance,
|
|
106
|
+
string.concat(
|
|
107
|
+
"V5 tier balance exceeds V4: owner=",
|
|
108
|
+
_addressToString(owner),
|
|
109
|
+
" tier=",
|
|
110
|
+
_uint256ToString(tierId),
|
|
111
|
+
" v4Balance=",
|
|
112
|
+
_uint256ToString(v4Balance),
|
|
113
|
+
" v5Balance=",
|
|
114
|
+
_uint256ToString(v5Balance)
|
|
115
|
+
)
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/// @notice Convert address to string (helper for error messages)
|
|
122
|
+
function _addressToString(address addr) private pure returns (string memory) {
|
|
123
|
+
bytes32 value = bytes32(uint256(uint160(addr)));
|
|
124
|
+
bytes memory alphabet = "0123456789abcdef";
|
|
125
|
+
bytes memory str = new bytes(42);
|
|
126
|
+
str[0] = "0";
|
|
127
|
+
str[1] = "x";
|
|
128
|
+
for (uint256 i = 0; i < 20; i++) {
|
|
129
|
+
str[2 + i * 2] = alphabet[uint8(value[i + 12] >> 4)];
|
|
130
|
+
str[3 + i * 2] = alphabet[uint8(value[i + 12] & 0x0f)];
|
|
131
|
+
}
|
|
132
|
+
return string(str);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/// @notice Convert uint256 to string (helper for error messages)
|
|
136
|
+
function _uint256ToString(uint256 value) private pure returns (string memory) {
|
|
137
|
+
if (value == 0) {
|
|
138
|
+
return "0";
|
|
139
|
+
}
|
|
140
|
+
uint256 temp = value;
|
|
141
|
+
uint256 digits;
|
|
142
|
+
while (temp != 0) {
|
|
143
|
+
digits++;
|
|
144
|
+
temp /= 10;
|
|
145
|
+
}
|
|
146
|
+
bytes memory buffer = new bytes(digits);
|
|
147
|
+
while (value != 0) {
|
|
148
|
+
digits -= 1;
|
|
149
|
+
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
|
|
150
|
+
value /= 10;
|
|
151
|
+
}
|
|
152
|
+
return string(buffer);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|