@zoralabs/coins 1.1.0 → 1.1.2
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/.turbo/turbo-build.log +102 -97
- package/CHANGELOG.md +14 -0
- package/LICENSE +90 -21
- package/abis/BaseCoin.json +6 -1
- package/abis/BaseZoraV4CoinHook.json +119 -0
- package/abis/Coin.json +6 -1
- package/abis/CoinTest.json +14 -0
- package/abis/CoinV4.json +6 -1
- package/abis/ContentCoinHook.json +119 -0
- package/abis/CreatorCoin.json +6 -1
- package/abis/CreatorCoinHook.json +119 -0
- package/abis/ERC165.json +21 -0
- package/abis/ERC165Upgradeable.json +44 -0
- package/abis/FeeEstimatorHook.json +119 -0
- package/abis/ICoin.json +5 -0
- package/abis/ICoinV3.json +5 -0
- package/abis/ICoinV4.json +5 -0
- package/abis/ICreatorCoin.json +5 -0
- package/abis/LiquidityMigrationTest.json +7 -0
- package/abis/UpgradeHooks.json +35 -0
- package/abis/UpgradesTest.json +21 -0
- package/addresses/8453.json +11 -7
- package/dist/index.cjs +6 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +6 -3
- package/dist/index.js.map +1 -1
- package/dist/wagmiGenerated.d.ts +15 -3
- package/dist/wagmiGenerated.d.ts.map +1 -1
- package/package/wagmiGenerated.ts +6 -3
- package/package.json +1 -1
- package/script/DeployUpgradeGate.s.sol +1 -1
- package/script/PrintRegisterUpgradePath.s.sol +35 -0
- package/script/UpgradeCoinImpl.sol +1 -1
- package/script/UpgradeHooks.s.sol +23 -0
- package/src/BaseCoin.sol +32 -10
- package/src/Coin.sol +7 -1
- package/src/CoinV4.sol +9 -3
- package/src/CreatorCoin.sol +7 -1
- package/src/ZoraFactoryImpl.sol +7 -1
- package/src/deployment/CoinsDeployerBase.sol +29 -9
- package/src/hooks/BaseZoraV4CoinHook.sol +124 -4
- package/src/hooks/ContentCoinHook.sol +7 -1
- package/src/hooks/CreatorCoinHook.sol +7 -1
- package/src/hooks/HookUpgradeGate.sol +7 -1
- package/src/interfaces/ICoin.sol +3 -0
- package/src/libs/CoinCommon.sol +7 -1
- package/src/libs/CoinConfigurationVersions.sol +7 -1
- package/src/libs/CoinConstants.sol +7 -1
- package/src/libs/CoinDopplerMultiCurve.sol +7 -1
- package/src/libs/CoinRewards.sol +7 -1
- package/src/libs/CoinRewardsV4.sol +25 -5
- package/src/libs/CoinSetup.sol +7 -1
- package/src/libs/CreatorCoinConstants.sol +7 -1
- package/src/libs/CreatorCoinRewards.sol +7 -1
- package/src/libs/DopplerMath.sol +7 -1
- package/src/libs/HooksDeployment.sol +20 -1
- package/src/libs/PoolStateReader.sol +7 -1
- package/src/libs/UniV4SwapHelper.sol +7 -1
- package/src/libs/UniV4SwapToCurrency.sol +7 -1
- package/src/libs/V4Liquidity.sol +34 -1
- package/src/types/PoolConfiguration.sol +7 -1
- package/src/utils/AutoSwapper.sol +7 -1
- package/src/version/ContractVersionBase.sol +1 -1
- package/test/Coin.t.sol +23 -0
- package/test/LiquidityMigration.t.sol +27 -0
- package/test/Upgrades.t.sol +180 -1
- package/test/utils/BaseTest.sol +5 -1
- /package/script/{DeployHooks.s.sol → DeployPostDeploymentHooks.s.sol} +0 -0
package/dist/wagmiGenerated.d.ts
CHANGED
|
@@ -983,7 +983,7 @@ export declare const coinABI: readonly [{
|
|
|
983
983
|
readonly internalType: "bool";
|
|
984
984
|
readonly type: "bool";
|
|
985
985
|
}];
|
|
986
|
-
readonly stateMutability: "
|
|
986
|
+
readonly stateMutability: "view";
|
|
987
987
|
}, {
|
|
988
988
|
readonly type: "function";
|
|
989
989
|
readonly inputs: readonly [];
|
|
@@ -1699,6 +1699,10 @@ export declare const coinABI: readonly [{
|
|
|
1699
1699
|
readonly type: "uint256";
|
|
1700
1700
|
}];
|
|
1701
1701
|
readonly name: "MaxShareToBeSoldExceeded";
|
|
1702
|
+
}, {
|
|
1703
|
+
readonly type: "error";
|
|
1704
|
+
readonly inputs: readonly [];
|
|
1705
|
+
readonly name: "NameIsRequired";
|
|
1702
1706
|
}, {
|
|
1703
1707
|
readonly type: "error";
|
|
1704
1708
|
readonly inputs: readonly [];
|
|
@@ -2436,7 +2440,7 @@ export declare const coinV4ABI: readonly [{
|
|
|
2436
2440
|
readonly internalType: "bool";
|
|
2437
2441
|
readonly type: "bool";
|
|
2438
2442
|
}];
|
|
2439
|
-
readonly stateMutability: "
|
|
2443
|
+
readonly stateMutability: "view";
|
|
2440
2444
|
}, {
|
|
2441
2445
|
readonly type: "function";
|
|
2442
2446
|
readonly inputs: readonly [];
|
|
@@ -3157,6 +3161,10 @@ export declare const coinV4ABI: readonly [{
|
|
|
3157
3161
|
readonly type: "uint256";
|
|
3158
3162
|
}];
|
|
3159
3163
|
readonly name: "MaxShareToBeSoldExceeded";
|
|
3164
|
+
}, {
|
|
3165
|
+
readonly type: "error";
|
|
3166
|
+
readonly inputs: readonly [];
|
|
3167
|
+
readonly name: "NameIsRequired";
|
|
3160
3168
|
}, {
|
|
3161
3169
|
readonly type: "error";
|
|
3162
3170
|
readonly inputs: readonly [];
|
|
@@ -3906,7 +3914,7 @@ export declare const creatorCoinABI: readonly [{
|
|
|
3906
3914
|
readonly internalType: "bool";
|
|
3907
3915
|
readonly type: "bool";
|
|
3908
3916
|
}];
|
|
3909
|
-
readonly stateMutability: "
|
|
3917
|
+
readonly stateMutability: "view";
|
|
3910
3918
|
}, {
|
|
3911
3919
|
readonly type: "function";
|
|
3912
3920
|
readonly inputs: readonly [];
|
|
@@ -4691,6 +4699,10 @@ export declare const creatorCoinABI: readonly [{
|
|
|
4691
4699
|
readonly type: "uint256";
|
|
4692
4700
|
}];
|
|
4693
4701
|
readonly name: "MaxShareToBeSoldExceeded";
|
|
4702
|
+
}, {
|
|
4703
|
+
readonly type: "error";
|
|
4704
|
+
readonly inputs: readonly [];
|
|
4705
|
+
readonly name: "NameIsRequired";
|
|
4694
4706
|
}, {
|
|
4695
4707
|
readonly type: "error";
|
|
4696
4708
|
readonly inputs: readonly [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wagmiGenerated.d.ts","sourceRoot":"","sources":["../package/wagmiGenerated.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2FjB,CAAA;AAMV,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqFjC,CAAA;AAMV,eAAO,MAAM,OAAO
|
|
1
|
+
{"version":3,"file":"wagmiGenerated.d.ts","sourceRoot":"","sources":["../package/wagmiGenerated.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2FjB,CAAA;AAMV,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqFjC,CAAA;AAMV,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuiCV,CAAA;AAMV,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwjCZ,CAAA;AAMV,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAioCjB,CAAA;AAMV,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyfd,CAAA;AAMV,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuBzB,CAAA;AAMV,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkIpB,CAAA;AAMV,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwBtB,CAAA;AAMV,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyjBrB,CAAA"}
|
|
@@ -617,7 +617,7 @@ export const coinABI = [
|
|
|
617
617
|
inputs: [{ name: 'interfaceId', internalType: 'bytes4', type: 'bytes4' }],
|
|
618
618
|
name: 'supportsInterface',
|
|
619
619
|
outputs: [{ name: '', internalType: 'bool', type: 'bool' }],
|
|
620
|
-
stateMutability: '
|
|
620
|
+
stateMutability: 'view',
|
|
621
621
|
},
|
|
622
622
|
{
|
|
623
623
|
type: 'function',
|
|
@@ -1229,6 +1229,7 @@ export const coinABI = [
|
|
|
1229
1229
|
],
|
|
1230
1230
|
name: 'MaxShareToBeSoldExceeded',
|
|
1231
1231
|
},
|
|
1232
|
+
{ type: 'error', inputs: [], name: 'NameIsRequired' },
|
|
1232
1233
|
{ type: 'error', inputs: [], name: 'NotInitializing' },
|
|
1233
1234
|
{ type: 'error', inputs: [], name: 'NotOwner' },
|
|
1234
1235
|
{ type: 'error', inputs: [], name: 'NumDiscoveryPositionsOutOfRange' },
|
|
@@ -1699,7 +1700,7 @@ export const coinV4ABI = [
|
|
|
1699
1700
|
inputs: [{ name: 'interfaceId', internalType: 'bytes4', type: 'bytes4' }],
|
|
1700
1701
|
name: 'supportsInterface',
|
|
1701
1702
|
outputs: [{ name: '', internalType: 'bool', type: 'bool' }],
|
|
1702
|
-
stateMutability: '
|
|
1703
|
+
stateMutability: 'view',
|
|
1703
1704
|
},
|
|
1704
1705
|
{
|
|
1705
1706
|
type: 'function',
|
|
@@ -2319,6 +2320,7 @@ export const coinV4ABI = [
|
|
|
2319
2320
|
],
|
|
2320
2321
|
name: 'MaxShareToBeSoldExceeded',
|
|
2321
2322
|
},
|
|
2323
|
+
{ type: 'error', inputs: [], name: 'NameIsRequired' },
|
|
2322
2324
|
{ type: 'error', inputs: [], name: 'NotInitializing' },
|
|
2323
2325
|
{ type: 'error', inputs: [], name: 'NotOwner' },
|
|
2324
2326
|
{ type: 'error', inputs: [], name: 'NumDiscoveryPositionsOutOfRange' },
|
|
@@ -2798,7 +2800,7 @@ export const creatorCoinABI = [
|
|
|
2798
2800
|
inputs: [{ name: 'interfaceId', internalType: 'bytes4', type: 'bytes4' }],
|
|
2799
2801
|
name: 'supportsInterface',
|
|
2800
2802
|
outputs: [{ name: '', internalType: 'bool', type: 'bool' }],
|
|
2801
|
-
stateMutability: '
|
|
2803
|
+
stateMutability: 'view',
|
|
2802
2804
|
},
|
|
2803
2805
|
{
|
|
2804
2806
|
type: 'function',
|
|
@@ -3477,6 +3479,7 @@ export const creatorCoinABI = [
|
|
|
3477
3479
|
],
|
|
3478
3480
|
name: 'MaxShareToBeSoldExceeded',
|
|
3479
3481
|
},
|
|
3482
|
+
{ type: 'error', inputs: [], name: 'NameIsRequired' },
|
|
3480
3483
|
{ type: 'error', inputs: [], name: 'NotInitializing' },
|
|
3481
3484
|
{ type: 'error', inputs: [], name: 'NotOwner' },
|
|
3482
3485
|
{ type: 'error', inputs: [], name: 'NumDiscoveryPositionsOutOfRange' },
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@ import {CoinsDeployerBase} from "../src/deployment/CoinsDeployerBase.sol";
|
|
|
6
6
|
|
|
7
7
|
contract DeployScript is CoinsDeployerBase {
|
|
8
8
|
function run() public {
|
|
9
|
-
CoinsDeployment memory deployment = readDeployment(
|
|
9
|
+
CoinsDeployment memory deployment = readDeployment(false);
|
|
10
10
|
|
|
11
11
|
vm.startBroadcast();
|
|
12
12
|
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.28;
|
|
3
|
+
|
|
4
|
+
import {ProxyDeployerScript, DeterministicDeployerAndCaller} from "@zoralabs/shared-contracts/deployment/ProxyDeployerScript.sol";
|
|
5
|
+
import {CoinsDeployerBase} from "../src/deployment/CoinsDeployerBase.sol";
|
|
6
|
+
import {IHooksUpgradeGate} from "../src/interfaces/IHooksUpgradeGate.sol";
|
|
7
|
+
|
|
8
|
+
import {console} from "forge-std/console.sol";
|
|
9
|
+
|
|
10
|
+
contract DeployScript is CoinsDeployerBase {
|
|
11
|
+
function run() public {
|
|
12
|
+
CoinsDeployment memory deployment = readDeployment(false);
|
|
13
|
+
|
|
14
|
+
address existingContentCoinHook = 0xd3D133469ADC85e01A4887404D8AC12d630e9040;
|
|
15
|
+
address existingCreatorCoinHook = 0xffF800B76768dA8AB6aab527021e4a6A91219040;
|
|
16
|
+
|
|
17
|
+
address[] memory baseImpls = new address[](1);
|
|
18
|
+
baseImpls[0] = existingContentCoinHook;
|
|
19
|
+
|
|
20
|
+
bytes memory contentCoinUpgradeCall = abi.encodeWithSelector(IHooksUpgradeGate.registerUpgradePath.selector, baseImpls, deployment.zoraV4CoinHook);
|
|
21
|
+
|
|
22
|
+
baseImpls[0] = existingCreatorCoinHook;
|
|
23
|
+
|
|
24
|
+
bytes memory creatorCoinUpgradeCall = abi.encodeWithSelector(IHooksUpgradeGate.registerUpgradePath.selector, baseImpls, deployment.creatorCoinHook);
|
|
25
|
+
|
|
26
|
+
printUpgradeFactoryCommand(deployment);
|
|
27
|
+
|
|
28
|
+
console.log("register upgrade gate target", deployment.hookUpgradeGate);
|
|
29
|
+
|
|
30
|
+
console.log("contentCoinUpgradeCall");
|
|
31
|
+
console.logBytes(contentCoinUpgradeCall);
|
|
32
|
+
console.log("creatorCoinUpgradeCall");
|
|
33
|
+
console.logBytes(creatorCoinUpgradeCall);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -6,7 +6,7 @@ import {CoinsDeployerBase} from "../src/deployment/CoinsDeployerBase.sol";
|
|
|
6
6
|
|
|
7
7
|
contract UpgradeCoinImpl is CoinsDeployerBase {
|
|
8
8
|
function run() public {
|
|
9
|
-
CoinsDeployment memory deployment = readDeployment(
|
|
9
|
+
CoinsDeployment memory deployment = readDeployment(false);
|
|
10
10
|
|
|
11
11
|
vm.startBroadcast();
|
|
12
12
|
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.26;
|
|
3
|
+
|
|
4
|
+
import {ProxyDeployerScript, DeterministicDeployerAndCaller} from "@zoralabs/shared-contracts/deployment/ProxyDeployerScript.sol";
|
|
5
|
+
import {CoinsDeployerBase} from "../src/deployment/CoinsDeployerBase.sol";
|
|
6
|
+
|
|
7
|
+
contract UpgradeHooks is CoinsDeployerBase {
|
|
8
|
+
function run() public {
|
|
9
|
+
CoinsDeployment memory deployment = readDeployment(false);
|
|
10
|
+
|
|
11
|
+
vm.startBroadcast();
|
|
12
|
+
|
|
13
|
+
// get deployer contract
|
|
14
|
+
deployment = deployHooks(deployment);
|
|
15
|
+
|
|
16
|
+
vm.stopBroadcast();
|
|
17
|
+
|
|
18
|
+
// save the deployment json
|
|
19
|
+
saveDeployment(deployment);
|
|
20
|
+
|
|
21
|
+
printUpgradeFactoryCommand(deployment);
|
|
22
|
+
}
|
|
23
|
+
}
|
package/src/BaseCoin.sol
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
// SPDX-License-Identifier:
|
|
2
|
-
|
|
1
|
+
// SPDX-License-Identifier: ZORA-DELAYED-OSL-v1
|
|
2
|
+
// This software is licensed under the Zora Delayed Open Source License.
|
|
3
|
+
// Under this license, you may use, copy, modify, and distribute this software for
|
|
4
|
+
// non-commercial purposes only. Commercial use and competitive products are prohibited
|
|
5
|
+
// until the "Open Date" (3 years from first public distribution or earlier at Zora's discretion),
|
|
6
|
+
// at which point this software automatically becomes available under the MIT License.
|
|
7
|
+
// Full license terms available at: https://docs.zora.co/coins/licensepragma solidity ^0.8.23;
|
|
3
8
|
|
|
4
9
|
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
|
5
10
|
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
|
|
@@ -16,6 +21,7 @@ import {IWETH} from "./interfaces/IWETH.sol";
|
|
|
16
21
|
|
|
17
22
|
import {Address} from "@openzeppelin/contracts/utils/Address.sol";
|
|
18
23
|
import {ERC20PermitUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PermitUpgradeable.sol";
|
|
24
|
+
import {ERC165Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol";
|
|
19
25
|
import {ReentrancyGuardUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol";
|
|
20
26
|
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
|
21
27
|
import {ContractVersionBase} from "./version/ContractVersionBase.sol";
|
|
@@ -40,7 +46,7 @@ import {UniV3BuySell, CoinConfig} from "./libs/UniV3BuySell.sol";
|
|
|
40
46
|
\$$$$$$ | $$$$$$ |$$$$$$\ $$ | \$$ |
|
|
41
47
|
\______/ \______/ \______|\__| \__|
|
|
42
48
|
*/
|
|
43
|
-
abstract contract BaseCoin is ICoin, ContractVersionBase, ERC20PermitUpgradeable, MultiOwnable, ReentrancyGuardUpgradeable {
|
|
49
|
+
abstract contract BaseCoin is ICoin, ContractVersionBase, ERC20PermitUpgradeable, MultiOwnable, ReentrancyGuardUpgradeable, ERC165Upgradeable {
|
|
44
50
|
using SafeERC20 for IERC20;
|
|
45
51
|
|
|
46
52
|
/// @notice The address of the protocol rewards contract
|
|
@@ -106,12 +112,14 @@ abstract contract BaseCoin is ICoin, ContractVersionBase, ERC20PermitUpgradeable
|
|
|
106
112
|
revert AddressZero();
|
|
107
113
|
}
|
|
108
114
|
|
|
109
|
-
|
|
110
|
-
|
|
115
|
+
_setNameAndSymbol(name_, symbol_);
|
|
116
|
+
|
|
117
|
+
// Set base contract state, leave name and symbol empty to save space.
|
|
118
|
+
__ERC20_init("", "");
|
|
119
|
+
|
|
120
|
+
// Set permit support without name later overriding name to match contract name.
|
|
121
|
+
__ERC20Permit_init("");
|
|
111
122
|
|
|
112
|
-
// Set base contract state
|
|
113
|
-
__ERC20_init(name_, symbol_);
|
|
114
|
-
__ERC20Permit_init(name_);
|
|
115
123
|
__MultiOwnable_init(owners_);
|
|
116
124
|
__ReentrancyGuard_init();
|
|
117
125
|
|
|
@@ -135,6 +143,13 @@ abstract contract BaseCoin is ICoin, ContractVersionBase, ERC20PermitUpgradeable
|
|
|
135
143
|
_transfer(address(this), payoutRecipient, CoinConstants.CREATOR_LAUNCH_REWARD);
|
|
136
144
|
}
|
|
137
145
|
|
|
146
|
+
/// @notice Returns the name of the token for EIP712 domain.
|
|
147
|
+
/// @notice This can change when the user changes the "name" of the token.
|
|
148
|
+
/// @dev Overrides the default implementation to align name getter with Permit support.
|
|
149
|
+
function _EIP712Name() internal pure override returns (string memory) {
|
|
150
|
+
return "Coin";
|
|
151
|
+
}
|
|
152
|
+
|
|
138
153
|
/// @notice Enables a user to burn their tokens
|
|
139
154
|
/// @param amount The amount of tokens to burn
|
|
140
155
|
function burn(uint256 amount) external {
|
|
@@ -167,6 +182,13 @@ abstract contract BaseCoin is ICoin, ContractVersionBase, ERC20PermitUpgradeable
|
|
|
167
182
|
}
|
|
168
183
|
|
|
169
184
|
function setNameAndSymbol(string memory newName, string memory newSymbol) external onlyOwner {
|
|
185
|
+
_setNameAndSymbol(newName, newSymbol);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function _setNameAndSymbol(string memory newName, string memory newSymbol) internal {
|
|
189
|
+
if (bytes(newName).length == 0) {
|
|
190
|
+
revert NameIsRequired();
|
|
191
|
+
}
|
|
170
192
|
_name = newName;
|
|
171
193
|
_symbol = newSymbol;
|
|
172
194
|
emit NameAndSymbolUpdated(msg.sender, newName, newSymbol);
|
|
@@ -182,12 +204,12 @@ abstract contract BaseCoin is ICoin, ContractVersionBase, ERC20PermitUpgradeable
|
|
|
182
204
|
|
|
183
205
|
/// @notice ERC165 interface support
|
|
184
206
|
/// @param interfaceId The interface ID to check
|
|
185
|
-
function supportsInterface(bytes4 interfaceId) public
|
|
207
|
+
function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165Upgradeable) returns (bool) {
|
|
186
208
|
return
|
|
209
|
+
super.supportsInterface(interfaceId) ||
|
|
187
210
|
interfaceId == type(ICoin).interfaceId ||
|
|
188
211
|
interfaceId == type(ICoinComments).interfaceId ||
|
|
189
212
|
interfaceId == type(IERC7572).interfaceId ||
|
|
190
|
-
interfaceId == type(IERC165).interfaceId ||
|
|
191
213
|
interfaceId == type(IHasRewardsRecipients).interfaceId;
|
|
192
214
|
}
|
|
193
215
|
|
package/src/Coin.sol
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
// SPDX-License-Identifier:
|
|
1
|
+
// SPDX-License-Identifier: ZORA-DELAYED-OSL-v1
|
|
2
|
+
// This software is licensed under the Zora Delayed Open Source License.
|
|
3
|
+
// Under this license, you may use, copy, modify, and distribute this software for
|
|
4
|
+
// non-commercial purposes only. Commercial use and competitive products are prohibited
|
|
5
|
+
// until the "Open Date" (3 years from first public distribution or earlier at Zora's discretion),
|
|
6
|
+
// at which point this software automatically becomes available under the MIT License.
|
|
7
|
+
// Full license terms available at: https://docs.zora.co/coins/license
|
|
2
8
|
pragma solidity ^0.8.23;
|
|
3
9
|
|
|
4
10
|
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
package/src/CoinV4.sol
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
// SPDX-License-Identifier:
|
|
1
|
+
// SPDX-License-Identifier: ZORA-DELAYED-OSL-v1
|
|
2
|
+
// This software is licensed under the Zora Delayed Open Source License.
|
|
3
|
+
// Under this license, you may use, copy, modify, and distribute this software for
|
|
4
|
+
// non-commercial purposes only. Commercial use and competitive products are prohibited
|
|
5
|
+
// until the "Open Date" (3 years from first public distribution or earlier at Zora's discretion),
|
|
6
|
+
// at which point this software automatically becomes available under the MIT License.
|
|
7
|
+
// Full license terms available at: https://docs.zora.co/coins/license
|
|
2
8
|
pragma solidity ^0.8.23;
|
|
3
9
|
|
|
4
10
|
import {IPoolManager, PoolKey, Currency, IHooks} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol";
|
|
@@ -109,8 +115,8 @@ contract CoinV4 is BaseCoin, ICoinV4 {
|
|
|
109
115
|
poolKey = newPoolKey;
|
|
110
116
|
}
|
|
111
117
|
|
|
112
|
-
function supportsInterface(bytes4 interfaceId) public
|
|
113
|
-
return interfaceId == type(IHasPoolKey).interfaceId || type(IHasSwapPath).interfaceId == interfaceId
|
|
118
|
+
function supportsInterface(bytes4 interfaceId) public view virtual override(BaseCoin, IERC165) returns (bool) {
|
|
119
|
+
return super.supportsInterface(interfaceId) || interfaceId == type(IHasPoolKey).interfaceId || type(IHasSwapPath).interfaceId == interfaceId;
|
|
114
120
|
}
|
|
115
121
|
|
|
116
122
|
/// @inheritdoc IHasSwapPath
|
package/src/CreatorCoin.sol
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
// SPDX-License-Identifier:
|
|
1
|
+
// SPDX-License-Identifier: ZORA-DELAYED-OSL-v1
|
|
2
|
+
// This software is licensed under the Zora Delayed Open Source License.
|
|
3
|
+
// Under this license, you may use, copy, modify, and distribute this software for
|
|
4
|
+
// non-commercial purposes only. Commercial use and competitive products are prohibited
|
|
5
|
+
// until the "Open Date" (3 years from first public distribution or earlier at Zora's discretion),
|
|
6
|
+
// at which point this software automatically becomes available under the MIT License.
|
|
7
|
+
// Full license terms available at: https://docs.zora.co/coins/license
|
|
2
8
|
pragma solidity ^0.8.28;
|
|
3
9
|
|
|
4
10
|
import {ICreatorCoin} from "./interfaces/ICreatorCoin.sol";
|
package/src/ZoraFactoryImpl.sol
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
// SPDX-License-Identifier:
|
|
1
|
+
// SPDX-License-Identifier: ZORA-DELAYED-OSL-v1
|
|
2
|
+
// This software is licensed under the Zora Delayed Open Source License.
|
|
3
|
+
// Under this license, you may use, copy, modify, and distribute this software for
|
|
4
|
+
// non-commercial purposes only. Commercial use and competitive products are prohibited
|
|
5
|
+
// until the "Open Date" (3 years from first public distribution or earlier at Zora's discretion),
|
|
6
|
+
// at which point this software automatically becomes available under the MIT License.
|
|
7
|
+
// Full license terms available at: https://docs.zora.co/coins/license
|
|
2
8
|
pragma solidity ^0.8.23;
|
|
3
9
|
|
|
4
10
|
import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol";
|
|
@@ -201,6 +201,19 @@ contract CoinsDeployerBase is ProxyDeployerScript {
|
|
|
201
201
|
return trustedMessageSenders;
|
|
202
202
|
}
|
|
203
203
|
|
|
204
|
+
function deployFactoryImpl(CoinsDeployment memory deployment) internal returns (address) {
|
|
205
|
+
return
|
|
206
|
+
address(
|
|
207
|
+
deployZoraFactoryImpl({
|
|
208
|
+
_coinV3Impl: deployment.coinV3Impl,
|
|
209
|
+
_coinV4Impl: deployment.coinV4Impl,
|
|
210
|
+
_creatorCoinImpl: deployment.creatorCoinImpl,
|
|
211
|
+
_contentCoinHook: deployment.zoraV4CoinHook,
|
|
212
|
+
_creatorCoinHook: deployment.creatorCoinHook
|
|
213
|
+
})
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
|
|
204
217
|
function deployImpls(CoinsDeployment memory deployment) internal returns (CoinsDeployment memory) {
|
|
205
218
|
// Deploy implementation contracts
|
|
206
219
|
deployment.coinV3Impl = address(deployCoinV3Impl());
|
|
@@ -218,21 +231,28 @@ contract CoinsDeployerBase is ProxyDeployerScript {
|
|
|
218
231
|
|
|
219
232
|
deployment.coinV4Impl = address(deployCoinV4Impl(deployment.zoraV4CoinHook));
|
|
220
233
|
deployment.creatorCoinImpl = address(deployCreatorCoinImpl(deployment.creatorCoinHook));
|
|
221
|
-
deployment.zoraFactoryImpl =
|
|
222
|
-
deployZoraFactoryImpl({
|
|
223
|
-
_coinV3Impl: deployment.coinV3Impl,
|
|
224
|
-
_coinV4Impl: deployment.coinV4Impl,
|
|
225
|
-
_creatorCoinImpl: deployment.creatorCoinImpl,
|
|
226
|
-
_contentCoinHook: deployment.zoraV4CoinHook,
|
|
227
|
-
_creatorCoinHook: deployment.creatorCoinHook
|
|
228
|
-
})
|
|
229
|
-
);
|
|
234
|
+
deployment.zoraFactoryImpl = deployFactoryImpl(deployment);
|
|
230
235
|
deployment.coinVersion = IVersionedContract(deployment.coinV4Impl).contractVersion();
|
|
231
236
|
deployment.buySupplyWithSwapRouterHook = address(deployBuySupplyWithSwapRouterHook(deployment));
|
|
232
237
|
|
|
233
238
|
return deployment;
|
|
234
239
|
}
|
|
235
240
|
|
|
241
|
+
function deployHooks(CoinsDeployment memory deployment) internal returns (CoinsDeployment memory) {
|
|
242
|
+
// Deploy hook first, then use its address for coin v4 impl
|
|
243
|
+
(IHooks zoraV4CoinHook, bytes32 usedSalt) = deployContentCoinHook(deployment);
|
|
244
|
+
deployment.zoraV4CoinHook = address(zoraV4CoinHook);
|
|
245
|
+
deployment.zoraV4CoinHookSalt = usedSalt;
|
|
246
|
+
|
|
247
|
+
(IHooks creatorCoinHook, bytes32 usedCreatorCoinHookSalt) = deployCreatorCoinHook(deployment);
|
|
248
|
+
deployment.creatorCoinHook = address(creatorCoinHook);
|
|
249
|
+
deployment.creatorCoinHookSalt = usedCreatorCoinHookSalt;
|
|
250
|
+
|
|
251
|
+
deployment.zoraFactoryImpl = deployFactoryImpl(deployment);
|
|
252
|
+
|
|
253
|
+
return deployment;
|
|
254
|
+
}
|
|
255
|
+
|
|
236
256
|
function deployZoraDeterministic(CoinsDeployment memory deployment, DeterministicDeployerAndCaller deployer) internal {
|
|
237
257
|
// read previously saved deterministic config
|
|
238
258
|
DeterministicContractConfig memory zoraConfig = readDeterministicContractConfig("zoraFactory");
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
// SPDX-License-Identifier:
|
|
1
|
+
// SPDX-License-Identifier: ZORA-DELAYED-OSL-v1
|
|
2
|
+
// This software is licensed under the Zora Delayed Open Source License.
|
|
3
|
+
// Under this license, you may use, copy, modify, and distribute this software for
|
|
4
|
+
// non-commercial purposes only. Commercial use and competitive products are prohibited
|
|
5
|
+
// until the "Open Date" (3 years from first public distribution or earlier at Zora's discretion),
|
|
6
|
+
// at which point this software automatically becomes available under the MIT License.
|
|
7
|
+
// Full license terms available at: https://docs.zora.co/coins/license
|
|
2
8
|
pragma solidity ^0.8.23;
|
|
3
9
|
|
|
4
10
|
import {BaseHook} from "@uniswap/v4-periphery/src/utils/BaseHook.sol";
|
|
@@ -24,6 +30,13 @@ import {CoinConfigurationVersions} from "../libs/CoinConfigurationVersions.sol";
|
|
|
24
30
|
import {IUpgradeableV4Hook} from "../interfaces/IUpgradeableV4Hook.sol";
|
|
25
31
|
import {IHooksUpgradeGate} from "../interfaces/IHooksUpgradeGate.sol";
|
|
26
32
|
import {MultiOwnable} from "../utils/MultiOwnable.sol";
|
|
33
|
+
import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
|
|
34
|
+
import {IUpgradeableDestinationV4Hook} from "../interfaces/IUpgradeableV4Hook.sol";
|
|
35
|
+
import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.sol";
|
|
36
|
+
import {BurnedPosition} from "../interfaces/IUpgradeableV4Hook.sol";
|
|
37
|
+
import {LiquidityAmounts} from "../utils/uniswap/LiquidityAmounts.sol";
|
|
38
|
+
import {TickMath} from "../utils/uniswap/TickMath.sol";
|
|
39
|
+
import {ContractVersionBase, IVersionedContract} from "../version/ContractVersionBase.sol";
|
|
27
40
|
|
|
28
41
|
/// @title ZoraV4CoinHook
|
|
29
42
|
/// @notice Uniswap V4 hook that automatically handles fee collection and reward distributions on every swap,
|
|
@@ -35,7 +48,7 @@ import {MultiOwnable} from "../utils/MultiOwnable.sol";
|
|
|
35
48
|
/// 2. Swaps collected fees to the backing currency through multi-hop paths
|
|
36
49
|
/// 3. Distributes converted fees as rewards
|
|
37
50
|
/// @author oveddan
|
|
38
|
-
abstract contract BaseZoraV4CoinHook is BaseHook, IZoraV4CoinHook {
|
|
51
|
+
abstract contract BaseZoraV4CoinHook is BaseHook, ContractVersionBase, IZoraV4CoinHook, ERC165, IUpgradeableDestinationV4Hook {
|
|
39
52
|
using BalanceDeltaLibrary for BalanceDelta;
|
|
40
53
|
|
|
41
54
|
/// @notice Mapping of trusted message senders - these are addresses that are trusted to provide a
|
|
@@ -115,6 +128,14 @@ abstract contract BaseZoraV4CoinHook is BaseHook, IZoraV4CoinHook {
|
|
|
115
128
|
return poolCoins[CoinCommon.hashPoolKey(key)];
|
|
116
129
|
}
|
|
117
130
|
|
|
131
|
+
/// @inheritdoc ERC165
|
|
132
|
+
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
|
|
133
|
+
return
|
|
134
|
+
super.supportsInterface(interfaceId) ||
|
|
135
|
+
interfaceId == type(IUpgradeableDestinationV4Hook).interfaceId ||
|
|
136
|
+
interfaceId == type(IVersionedContract).interfaceId;
|
|
137
|
+
}
|
|
138
|
+
|
|
118
139
|
/// @notice Internal fn generating the positions for a given pool key.
|
|
119
140
|
/// @param coin The coin address.
|
|
120
141
|
/// @param key The pool key for the coin.
|
|
@@ -131,6 +152,12 @@ abstract contract BaseZoraV4CoinHook is BaseHook, IZoraV4CoinHook {
|
|
|
131
152
|
/// @param key The pool key.
|
|
132
153
|
/// @return selector The selector of the afterInitialize hook to confirm the action.
|
|
133
154
|
function _afterInitialize(address sender, PoolKey calldata key, uint160, int24) internal override returns (bytes4) {
|
|
155
|
+
// If the sender is the hook itself, we assume this is a migration and we return early.
|
|
156
|
+
if (sender == address(this)) {
|
|
157
|
+
return BaseHook.afterInitialize.selector;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Otherwise, we initialize the hook positions.
|
|
134
161
|
address coin = sender;
|
|
135
162
|
if (!CoinConfigurationVersions.isV4(coinVersionLookup.getVersionForDeployedCoin(coin))) {
|
|
136
163
|
revert NotACoin(coin);
|
|
@@ -143,9 +170,103 @@ abstract contract BaseZoraV4CoinHook is BaseHook, IZoraV4CoinHook {
|
|
|
143
170
|
return BaseHook.afterInitialize.selector;
|
|
144
171
|
}
|
|
145
172
|
|
|
173
|
+
/// @inheritdoc IUpgradeableDestinationV4Hook
|
|
174
|
+
function initializeFromMigration(
|
|
175
|
+
PoolKey calldata poolKey,
|
|
176
|
+
address coin,
|
|
177
|
+
uint160 sqrtPriceX96,
|
|
178
|
+
BurnedPosition[] calldata migratedLiquidity,
|
|
179
|
+
bytes calldata
|
|
180
|
+
) external {
|
|
181
|
+
address oldHook = msg.sender;
|
|
182
|
+
address newHook = address(this);
|
|
183
|
+
|
|
184
|
+
// Verify that the caller (new hook) is authorized to perform this migration
|
|
185
|
+
// Only registered upgrade paths in the upgrade gate are allowed to migrate liquidity
|
|
186
|
+
if (!upgradeGate.isRegisteredUpgradePath(oldHook, newHook)) {
|
|
187
|
+
revert IUpgradeableV4Hook.UpgradePathNotRegistered(oldHook, newHook);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Create a new pool key with the same parameters but pointing to this hook
|
|
191
|
+
// This ensures the migrated pool uses the new hook implementation
|
|
192
|
+
PoolKey memory newKey = PoolKey({
|
|
193
|
+
currency0: poolKey.currency0,
|
|
194
|
+
currency1: poolKey.currency1,
|
|
195
|
+
fee: poolKey.fee,
|
|
196
|
+
tickSpacing: poolKey.tickSpacing,
|
|
197
|
+
hooks: IHooks(newHook)
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
// Initialize the new pool with the migrated price
|
|
201
|
+
// This creates the actual Uniswap V4 pool with the current market price
|
|
202
|
+
// A side effect is that the _afterInitialize hook is called here, so we find self-referential calls there and return early.
|
|
203
|
+
// This preserves the previous sqrtPriceX96 in the new pools.
|
|
204
|
+
poolManager.initialize(newKey, sqrtPriceX96);
|
|
205
|
+
|
|
206
|
+
// Convert the burned/migrated liquidity positions into new LP positions
|
|
207
|
+
// This recreates the liquidity structure from the old hook in the new hook
|
|
208
|
+
LpPosition[] memory positions = V4Liquidity.generatePositionsFromMigratedLiquidity(sqrtPriceX96, migratedLiquidity);
|
|
209
|
+
|
|
210
|
+
// Store the positions and mint the initial liquidity into the new pool
|
|
211
|
+
_initializeForPositions(newKey, coin, positions);
|
|
212
|
+
|
|
213
|
+
// Handle any remaining token balances by adding them to the last position
|
|
214
|
+
// This ensures no tokens are left unminted during the migration process
|
|
215
|
+
_mintExtraLiquidityAtLastPosition(sqrtPriceX96, newKey);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/// @notice Internal fn to add any remaining token balances to the last liquidity position.
|
|
219
|
+
/// @param sqrtPriceX96 The sqrt price x96.
|
|
220
|
+
/// @param poolKey The pool key.
|
|
221
|
+
function _mintExtraLiquidityAtLastPosition(uint160 sqrtPriceX96, PoolKey memory poolKey) internal {
|
|
222
|
+
// Check if there are any leftover token balances in the hook after migration
|
|
223
|
+
// These could result from rounding or partial liquidity transfers
|
|
224
|
+
uint256 currency0Balance = poolKey.currency0.balanceOfSelf();
|
|
225
|
+
uint256 currency1Balance = poolKey.currency1.balanceOfSelf();
|
|
226
|
+
|
|
227
|
+
// Get the stored positions for this pool to access the last position
|
|
228
|
+
LpPosition[] storage positions = poolCoins[CoinCommon.hashPoolKey(poolKey)].positions;
|
|
229
|
+
|
|
230
|
+
// Only proceed if there are actually leftover tokens to mint
|
|
231
|
+
if (currency0Balance > 0 || currency1Balance > 0) {
|
|
232
|
+
// Get reference to the last position where we'll add the extra liquidity
|
|
233
|
+
LpPosition storage lastPosition = positions[positions.length - 1];
|
|
234
|
+
|
|
235
|
+
// Calculate how much liquidity we can create with the remaining token balances
|
|
236
|
+
// This uses the current pool price and the last position's tick range
|
|
237
|
+
uint128 newLiquidity = LiquidityAmounts.getLiquidityForAmounts(
|
|
238
|
+
sqrtPriceX96,
|
|
239
|
+
TickMath.getSqrtPriceAtTick(lastPosition.tickLower),
|
|
240
|
+
TickMath.getSqrtPriceAtTick(lastPosition.tickUpper),
|
|
241
|
+
currency0Balance,
|
|
242
|
+
currency1Balance
|
|
243
|
+
);
|
|
244
|
+
|
|
245
|
+
// Create a temporary array with just the last position to mint the extra liquidity
|
|
246
|
+
LpPosition[] memory newPositions = new LpPosition[](1);
|
|
247
|
+
newPositions[0] = lastPosition;
|
|
248
|
+
newPositions[0].liquidity = newLiquidity; // Set the calculated liquidity amount
|
|
249
|
+
|
|
250
|
+
// Mint the extra liquidity into the pool using the V4 liquidity manager
|
|
251
|
+
V4Liquidity.lockAndMint(poolManager, poolKey, newPositions);
|
|
252
|
+
|
|
253
|
+
// Update our internal tracking of the last position's liquidity
|
|
254
|
+
// This keeps our records in sync with the actual pool state
|
|
255
|
+
positions[positions.length - 1].liquidity += newPositions[0].liquidity;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/// @notice Saves the positions for the coin and mints them into the pool
|
|
260
|
+
/// @param key The pool key.
|
|
261
|
+
/// @param coin The coin address.
|
|
262
|
+
/// @param positions The positions.
|
|
146
263
|
function _initializeForPositions(PoolKey memory key, address coin, LpPosition[] memory positions) internal {
|
|
264
|
+
// Store the association between this pool and its coin + positions
|
|
265
|
+
// This creates the internal mapping that tracks which coin owns which positions
|
|
147
266
|
poolCoins[CoinCommon.hashPoolKey(key)] = PoolCoin({coin: coin, positions: positions});
|
|
148
267
|
|
|
268
|
+
// Mint all the calculated liquidity positions into the Uniswap V4 pool
|
|
269
|
+
// This actually provides the liquidity that users can trade against
|
|
149
270
|
V4Liquidity.lockAndMint(poolManager, key, positions);
|
|
150
271
|
}
|
|
151
272
|
|
|
@@ -181,7 +302,6 @@ abstract contract BaseZoraV4CoinHook is BaseHook, IZoraV4CoinHook {
|
|
|
181
302
|
// collect lp fees
|
|
182
303
|
(int128 fees0, int128 fees1) = V4Liquidity.collectFees(poolManager, key, poolCoins[poolKeyHash].positions);
|
|
183
304
|
|
|
184
|
-
// mint the lp reward
|
|
185
305
|
(uint128 marketRewardsAmount0, uint128 marketRewardsAmount1) = CoinRewardsV4.mintLpReward(poolManager, key, fees0, fees1);
|
|
186
306
|
|
|
187
307
|
// convert remaining fees to payout currency for market rewards
|
|
@@ -239,7 +359,7 @@ abstract contract BaseZoraV4CoinHook is BaseHook, IZoraV4CoinHook {
|
|
|
239
359
|
}
|
|
240
360
|
|
|
241
361
|
/// @inheritdoc IUpgradeableV4Hook
|
|
242
|
-
function migrateLiquidity(address newHook, PoolKey memory poolKey, bytes calldata additionalData) external
|
|
362
|
+
function migrateLiquidity(address newHook, PoolKey memory poolKey, bytes calldata additionalData) external returns (PoolKey memory newPoolKey) {
|
|
243
363
|
bytes32 poolKeyHash = CoinCommon.hashPoolKey(poolKey);
|
|
244
364
|
PoolCoin storage poolCoin = poolCoins[poolKeyHash];
|
|
245
365
|
// check that the coin associated with the poolkey is the caller
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
// SPDX-License-Identifier:
|
|
1
|
+
// SPDX-License-Identifier: ZORA-DELAYED-OSL-v1
|
|
2
|
+
// This software is licensed under the Zora Delayed Open Source License.
|
|
3
|
+
// Under this license, you may use, copy, modify, and distribute this software for
|
|
4
|
+
// non-commercial purposes only. Commercial use and competitive products are prohibited
|
|
5
|
+
// until the "Open Date" (3 years from first public distribution or earlier at Zora's discretion),
|
|
6
|
+
// at which point this software automatically becomes available under the MIT License.
|
|
7
|
+
// Full license terms available at: https://docs.zora.co/coins/license
|
|
2
8
|
pragma solidity ^0.8.28;
|
|
3
9
|
|
|
4
10
|
import {IPoolManager, IDeployedCoinVersionLookup, IHasRewardsRecipients, Currency, BaseZoraV4CoinHook} from "./BaseZoraV4CoinHook.sol";
|