@zoralabs/coins 0.7.1 → 1.0.0
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 +106 -84
- package/CHANGELOG.md +68 -0
- package/abis/BadImpl.json +15 -0
- package/abis/BalanceDeltaLibrary.json +15 -0
- package/abis/BaseCoin.json +1350 -0
- package/abis/BaseCoinDeployHook.json +78 -0
- package/abis/BaseHook.json +897 -0
- package/abis/BaseTest.json +60 -91
- package/abis/BeforeSwapDeltaLibrary.json +15 -0
- package/abis/BuySupplyWithSwapRouterHook.json +126 -0
- package/abis/Coin.json +214 -150
- package/abis/CoinConstants.json +65 -0
- package/abis/CoinDopplerMultiCurve.json +38 -0
- package/abis/CoinRewardsV4.json +54 -0
- package/abis/CoinTest.json +66 -111
- package/abis/CoinUniV4Test.json +1053 -0
- package/abis/CoinV4.json +1687 -0
- package/abis/CurrencyLibrary.json +25 -0
- package/abis/DeployHooks.json +9 -0
- package/abis/DeployScript.json +47 -0
- package/abis/DeployedCoinVersionLookup.json +21 -0
- package/abis/DeployedCoinVersionLookupTest.json +716 -0
- package/abis/DifferentNamespaceVersionLookup.json +39 -0
- package/abis/DopplerUniswapV3Test.json +62 -184
- package/abis/ERC20.json +310 -0
- package/abis/FactoryTest.json +98 -98
- package/abis/FakeHookNoInterface.json +21 -0
- package/abis/FeeEstimatorHook.json +1528 -0
- package/abis/Hooks.json +28 -0
- package/abis/HooksDeployment.json +23 -0
- package/abis/HooksTest.json +698 -0
- package/abis/IAllowanceTransfer.json +486 -0
- package/abis/ICoin.json +62 -69
- package/abis/ICoinDeployHook.json +31 -0
- package/abis/ICoinV3.json +879 -0
- package/abis/ICoinV4.json +915 -0
- package/abis/IContractMetadata.json +28 -0
- package/abis/IDeployedCoinVersionLookup.json +21 -0
- package/abis/IEIP712.json +15 -0
- package/abis/IEIP712_v4.json +15 -0
- package/abis/IERC20Minimal.json +172 -0
- package/abis/IERC6909Claims.json +288 -0
- package/abis/IERC721.json +36 -36
- package/abis/IERC721Permit_v4.json +88 -0
- package/abis/IExtsload.json +64 -0
- package/abis/IExttload.json +40 -0
- package/abis/IHasAfterCoinDeploy.json +31 -0
- package/abis/IHasContractName.json +15 -0
- package/abis/IHasPoolKey.json +42 -0
- package/abis/IHasRewardsRecipients.json +54 -0
- package/abis/IHasSwapPath.json +60 -0
- package/abis/IHooks.json +789 -0
- package/abis/IImmutableState.json +15 -0
- package/abis/IMsgSender.json +15 -0
- package/abis/IMulticall_v4.json +21 -0
- package/abis/INotifier.json +187 -0
- package/abis/IPermit2.json +865 -0
- package/abis/IPermit2Forwarder.json +138 -0
- package/abis/IPoolConfigEncoding.json +46 -0
- package/abis/IPoolInitializer_v4.json +53 -0
- package/abis/IPoolManager.json +1286 -0
- package/abis/IPositionManager.json +712 -0
- package/abis/IProtocolFees.json +174 -0
- package/abis/ISignatureTransfer.json +394 -0
- package/abis/ISubscriber.json +89 -0
- package/abis/ISwapPathRouter.json +92 -0
- package/abis/ISwapRouter.json +82 -0
- package/abis/IUniversalRouter.json +61 -0
- package/abis/IUnlockCallback.json +21 -0
- package/abis/IUnorderedNonce.json +44 -0
- package/abis/IV4Quoter.json +310 -0
- package/abis/IV4Router.json +47 -0
- package/abis/IZoraFactory.json +328 -4
- package/abis/IZoraV4CoinHook.json +427 -0
- package/abis/ImmutableState.json +36 -0
- package/abis/LPFeeLibrary.json +65 -0
- package/abis/MockERC20.json +21 -0
- package/abis/MultiOwnableTest.json +60 -91
- package/abis/{CoinConfigurationVersions.json → Position.json} +1 -1
- package/abis/PrintUpgradeCommand.json +9 -0
- package/abis/ProxyShim.json +24 -0
- package/abis/Simulate.json +0 -91
- package/abis/StateLibrary.json +80 -0
- package/abis/TestDeployedCoinVersionLookupImplementation.json +39 -0
- package/abis/TestV4Swap.json +9 -0
- package/abis/{CoinSetup.json → UniV3BuySell.json} +5 -0
- package/abis/UniV3Errors.json +32 -0
- package/abis/UpgradeCoinImpl.json +47 -0
- package/abis/UpgradeFactoryImpl.json +9 -0
- package/abis/UpgradesTest.json +671 -0
- package/abis/Vm.json +1482 -111
- package/abis/VmSafe.json +856 -32
- package/abis/ZoraFactoryImpl.json +450 -1
- package/abis/ZoraV4CoinHook.json +1439 -0
- package/addresses/8453.json +8 -3
- package/addresses/84532.json +8 -3
- package/dist/index.cjs +1998 -184
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1989 -178
- package/dist/index.js.map +1 -1
- package/dist/wagmiGenerated.d.ts +2852 -688
- package/dist/wagmiGenerated.d.ts.map +1 -1
- package/package/wagmiGenerated.ts +1992 -173
- package/package.json +7 -2
- package/remappings.txt +6 -1
- package/script/CoinsDeployerBase.sol +105 -10
- package/script/DeployDevFactory.s.sol +21 -0
- package/script/DeployHooks.s.sol +22 -0
- package/script/PrintUpgradeCommand.s.sol +13 -0
- package/script/Simulate.s.sol +4 -12
- package/script/TestBackingCoinSwap.s.sol +146 -0
- package/script/TestV4Swap.s.sol +136 -0
- package/script/UpgradeCoinImpl.sol +2 -2
- package/script/UpgradeFactoryImpl.s.sol +23 -0
- package/src/BaseCoin.sol +176 -0
- package/src/Coin.sol +93 -515
- package/src/CoinV4.sol +121 -0
- package/src/ZoraFactoryImpl.sol +257 -57
- package/src/hooks/ZoraV4CoinHook.sol +195 -0
- package/src/hooks/deployment/BaseCoinDeployHook.sol +62 -0
- package/src/hooks/deployment/BuySupplyWithSwapRouterHook.sol +80 -0
- package/src/interfaces/ICoin.sol +35 -39
- package/src/interfaces/ICoinDeployHook.sol +8 -0
- package/src/interfaces/ICoinV3.sol +71 -0
- package/src/interfaces/ICoinV4.sol +69 -0
- package/src/interfaces/IDeployedCoinVersionLookup.sol +11 -0
- package/src/interfaces/IMsgSender.sol +9 -0
- package/src/interfaces/IPoolConfigEncoding.sol +14 -0
- package/src/interfaces/ISwapPathRouter.sol +14 -0
- package/src/interfaces/ISwapRouter.sol +1 -35
- package/src/interfaces/IZoraFactory.sol +97 -7
- package/src/interfaces/IZoraV4CoinHook.sol +116 -0
- package/src/libs/CoinCommon.sol +15 -0
- package/src/libs/CoinConfigurationVersions.sol +116 -1
- package/src/{utils → libs}/CoinConstants.sol +11 -6
- package/src/libs/CoinDopplerMultiCurve.sol +134 -0
- package/src/libs/CoinDopplerUniV3.sol +19 -171
- package/src/libs/CoinRewards.sol +195 -0
- package/src/libs/CoinRewardsV4.sol +180 -0
- package/src/libs/CoinSetup.sol +40 -20
- package/src/libs/CoinSetupV3.sol +50 -0
- package/src/libs/DopplerMath.sol +156 -0
- package/src/libs/HooksDeployment.sol +84 -0
- package/src/libs/MarketConstants.sol +4 -0
- package/src/libs/PoolStateReader.sol +22 -0
- package/src/libs/UniV3BuySell.sol +231 -0
- package/src/libs/UniV3Errors.sol +11 -0
- package/src/libs/UniV4SwapHelper.sol +65 -0
- package/src/libs/UniV4SwapToCurrency.sol +109 -0
- package/src/libs/V4Liquidity.sol +129 -0
- package/src/types/PoolConfiguration.sol +15 -0
- package/src/utils/DeployedCoinVersionLookup.sol +52 -0
- package/src/version/ContractVersionBase.sol +1 -1
- package/test/Coin.t.sol +94 -101
- package/test/CoinDopplerUniV3.t.sol +35 -184
- package/test/CoinUniV4.t.sol +752 -0
- package/test/DeploymentHooks.t.sol +270 -0
- package/test/Factory.t.sol +84 -50
- package/test/MultiOwnable.t.sol +6 -3
- package/test/Upgrades.t.sol +68 -0
- package/test/mocks/MockERC20.sol +12 -0
- package/test/utils/BaseTest.sol +124 -59
- package/test/utils/DeployedCoinVersionLookup.t.sol +127 -0
- package/test/utils/FeeEstimatorHook.sol +84 -0
- package/test/utils/ProxyShim.sol +17 -0
- package/wagmi.config.ts +10 -9
- package/src/libs/CoinLegacy.sol +0 -48
package/src/Coin.sol
CHANGED
|
@@ -2,10 +2,7 @@
|
|
|
2
2
|
pragma solidity ^0.8.23;
|
|
3
3
|
|
|
4
4
|
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
|
5
|
-
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
|
|
6
5
|
import {ICoin, PoolConfiguration} from "./interfaces/ICoin.sol";
|
|
7
|
-
import {ICoinComments} from "./interfaces/ICoinComments.sol";
|
|
8
|
-
import {IERC7572} from "./interfaces/IERC7572.sol";
|
|
9
6
|
import {IUniswapV3Factory} from "./interfaces/IUniswapV3Factory.sol";
|
|
10
7
|
import {IUniswapV3Pool} from "./interfaces/IUniswapV3Pool.sol";
|
|
11
8
|
import {ISwapRouter} from "./interfaces/ISwapRouter.sol";
|
|
@@ -18,15 +15,15 @@ import {ERC20PermitUpgradeable} from "@openzeppelin/contracts-upgradeable/token/
|
|
|
18
15
|
import {ReentrancyGuardUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol";
|
|
19
16
|
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
|
20
17
|
import {ContractVersionBase} from "./version/ContractVersionBase.sol";
|
|
21
|
-
import {CoinConstants} from "./utils/CoinConstants.sol";
|
|
22
18
|
import {MultiOwnable} from "./utils/MultiOwnable.sol";
|
|
23
|
-
import {
|
|
24
|
-
import {TickMath} from "./utils/uniswap/TickMath.sol";
|
|
25
|
-
import {LiquidityAmounts} from "./utils/uniswap/LiquidityAmounts.sol";
|
|
26
|
-
import {CoinSetup} from "./libs/CoinSetup.sol";
|
|
19
|
+
import {CoinConstants} from "./libs/CoinConstants.sol";
|
|
27
20
|
import {MarketConstants} from "./libs/MarketConstants.sol";
|
|
28
21
|
import {LpPosition} from "./types/LpPosition.sol";
|
|
29
22
|
import {PoolState} from "./types/PoolState.sol";
|
|
23
|
+
import {CoinSetupV3, UniV3Config, CoinV3Config} from "./libs/CoinSetupV3.sol";
|
|
24
|
+
import {UniV3BuySell, CoinConfig, SellResult} from "./libs/UniV3BuySell.sol";
|
|
25
|
+
import {BaseCoin} from "./BaseCoin.sol";
|
|
26
|
+
import {ICoinV3} from "./interfaces/ICoinV3.sol";
|
|
30
27
|
|
|
31
28
|
/*
|
|
32
29
|
$$$$$$\ $$$$$$\ $$$$$$\ $$\ $$\
|
|
@@ -38,158 +35,96 @@ import {PoolState} from "./types/PoolState.sol";
|
|
|
38
35
|
\$$$$$$ | $$$$$$ |$$$$$$\ $$ | \$$ |
|
|
39
36
|
\______/ \______/ \______|\__| \__|
|
|
40
37
|
*/
|
|
41
|
-
contract Coin is
|
|
38
|
+
contract Coin is BaseCoin, ICoinV3 {
|
|
42
39
|
using SafeERC20 for IERC20;
|
|
43
40
|
|
|
44
|
-
/// @notice The address of the WETH contract
|
|
45
|
-
address public immutable WETH;
|
|
46
|
-
/// @notice The address of the Uniswap V3 factory
|
|
47
41
|
address public immutable v3Factory;
|
|
48
42
|
/// @notice The address of the Uniswap V3 swap router
|
|
49
43
|
address public immutable swapRouter;
|
|
50
|
-
/// @notice The address of the Airlock contract, ownership is used for a protocol fee split.
|
|
51
|
-
address public immutable airlock;
|
|
52
|
-
/// @notice The address of the protocol rewards contract
|
|
53
|
-
address public immutable protocolRewards;
|
|
54
|
-
/// @notice The address of the protocol reward recipient
|
|
55
|
-
address public immutable protocolRewardRecipient;
|
|
56
|
-
|
|
57
|
-
/// @notice The metadata URI
|
|
58
|
-
string public tokenURI;
|
|
59
|
-
/// @notice The address of the coin creator
|
|
60
|
-
address public payoutRecipient;
|
|
61
|
-
/// @notice The address of the platform referrer
|
|
62
|
-
address public platformReferrer;
|
|
63
44
|
/// @notice The address of the Uniswap V3 pool
|
|
64
45
|
address public poolAddress;
|
|
65
|
-
/// @notice The address of the currency
|
|
66
|
-
address public currency;
|
|
67
46
|
|
|
47
|
+
/// @notice The state of the market
|
|
48
|
+
bytes public market;
|
|
49
|
+
uint8 public marketVersion;
|
|
50
|
+
|
|
51
|
+
/// @notice The address of the WETH contract
|
|
52
|
+
address public immutable WETH;
|
|
53
|
+
|
|
54
|
+
/// @notice deprecated
|
|
68
55
|
PoolConfiguration public poolConfiguration;
|
|
69
56
|
|
|
70
|
-
|
|
71
|
-
/// @dev This is a legacy function for compatibility with doppler default state
|
|
72
|
-
/// @return asset The address of the asset
|
|
73
|
-
/// @return numeraire The address of the numeraire
|
|
74
|
-
/// @return tickLower The lower tick
|
|
75
|
-
/// @return tickUpper The upper tick
|
|
76
|
-
/// @return numPositions The number of discovery positions
|
|
77
|
-
/// @return isInitialized Whether the pool is initialized
|
|
78
|
-
/// @return isExited Whether the pool is exited
|
|
79
|
-
/// @return maxShareToBeSold The maximum share to be sold
|
|
80
|
-
/// @return totalTokensOnBondingCurve The total tokens on the bonding curve
|
|
81
|
-
function poolState()
|
|
82
|
-
external
|
|
83
|
-
view
|
|
84
|
-
returns (
|
|
85
|
-
address asset,
|
|
86
|
-
address numeraire,
|
|
87
|
-
int24 tickLower,
|
|
88
|
-
int24 tickUpper,
|
|
89
|
-
uint16 numPositions,
|
|
90
|
-
bool isInitialized,
|
|
91
|
-
bool isExited,
|
|
92
|
-
uint256 maxShareToBeSold,
|
|
93
|
-
uint256 totalTokensOnBondingCurve
|
|
94
|
-
)
|
|
95
|
-
{
|
|
96
|
-
asset = address(this);
|
|
97
|
-
numeraire = currency;
|
|
98
|
-
tickLower = poolConfiguration.tickLower;
|
|
99
|
-
tickUpper = poolConfiguration.tickUpper;
|
|
100
|
-
numPositions = poolConfiguration.numPositions;
|
|
101
|
-
isInitialized = true;
|
|
102
|
-
isExited = false;
|
|
103
|
-
maxShareToBeSold = poolConfiguration.maxDiscoverySupplyShare;
|
|
104
|
-
totalTokensOnBondingCurve = POOL_LAUNCH_SUPPLY;
|
|
105
|
-
}
|
|
57
|
+
LpPosition[] public positions;
|
|
106
58
|
|
|
107
59
|
/**
|
|
108
60
|
* @notice The constructor for the static Coin contract deployment shared across all Coins.
|
|
109
|
-
* @param
|
|
110
|
-
* @param
|
|
111
|
-
* @param
|
|
112
|
-
* @param
|
|
113
|
-
* @param
|
|
114
|
-
* @param
|
|
61
|
+
* @param protocolRewardRecipient_ The address of the protocol reward recipient
|
|
62
|
+
* @param protocolRewards_ The address of the protocol rewards contract
|
|
63
|
+
* @param weth_ The address of the WETH contract
|
|
64
|
+
* @param v3Factory_ The address of the Uniswap V3 factory
|
|
65
|
+
* @param swapRouter_ The address of the Uniswap V3 swap router
|
|
66
|
+
* @param airlock_ The address of the Airlock contract, ownership is used for a protocol fee split.
|
|
115
67
|
*/
|
|
116
68
|
constructor(
|
|
117
|
-
address
|
|
118
|
-
address
|
|
119
|
-
address
|
|
120
|
-
address
|
|
121
|
-
address
|
|
122
|
-
address
|
|
123
|
-
) initializer {
|
|
124
|
-
if (
|
|
125
|
-
revert AddressZero();
|
|
126
|
-
}
|
|
127
|
-
if (_protocolRewards == address(0)) {
|
|
128
|
-
revert AddressZero();
|
|
129
|
-
}
|
|
130
|
-
if (_weth == address(0)) {
|
|
69
|
+
address protocolRewardRecipient_,
|
|
70
|
+
address protocolRewards_,
|
|
71
|
+
address weth_,
|
|
72
|
+
address v3Factory_,
|
|
73
|
+
address swapRouter_,
|
|
74
|
+
address airlock_
|
|
75
|
+
) BaseCoin(protocolRewardRecipient_, protocolRewards_, airlock_) initializer {
|
|
76
|
+
if (v3Factory_ == address(0)) {
|
|
131
77
|
revert AddressZero();
|
|
132
78
|
}
|
|
133
|
-
if (
|
|
79
|
+
if (swapRouter_ == address(0)) {
|
|
134
80
|
revert AddressZero();
|
|
135
81
|
}
|
|
136
|
-
if (
|
|
82
|
+
if (airlock_ == address(0)) {
|
|
137
83
|
revert AddressZero();
|
|
138
84
|
}
|
|
139
|
-
if (
|
|
85
|
+
if (weth_ == address(0)) {
|
|
140
86
|
revert AddressZero();
|
|
141
87
|
}
|
|
88
|
+
swapRouter = swapRouter_;
|
|
89
|
+
v3Factory = v3Factory_;
|
|
142
90
|
|
|
143
|
-
|
|
144
|
-
protocolRewards = _protocolRewards;
|
|
145
|
-
WETH = _weth;
|
|
146
|
-
swapRouter = _swapRouter;
|
|
147
|
-
v3Factory = _v3Factory;
|
|
148
|
-
airlock = _airlock;
|
|
91
|
+
WETH = weth_;
|
|
149
92
|
}
|
|
150
93
|
|
|
151
|
-
/// @
|
|
152
|
-
/// @param payoutRecipient_ The address of the coin creator
|
|
153
|
-
/// @param tokenURI_ The metadata URI
|
|
154
|
-
/// @param name_ The coin name
|
|
155
|
-
/// @param symbol_ The coin symbol
|
|
156
|
-
/// @param poolConfig_ The parameters for the v3 pool and liquidity
|
|
157
|
-
/// @param platformReferrer_ The address of the platform referrer
|
|
94
|
+
/// @inheritdoc ICoinV3
|
|
158
95
|
function initialize(
|
|
159
96
|
address payoutRecipient_,
|
|
160
97
|
address[] memory owners_,
|
|
161
98
|
string memory tokenURI_,
|
|
162
99
|
string memory name_,
|
|
163
100
|
string memory symbol_,
|
|
164
|
-
|
|
165
|
-
address
|
|
101
|
+
address platformReferrer_,
|
|
102
|
+
address currency_,
|
|
103
|
+
address poolAddress_,
|
|
104
|
+
PoolConfiguration memory poolConfiguration_,
|
|
105
|
+
LpPosition[] memory positions_
|
|
166
106
|
) public initializer {
|
|
167
|
-
|
|
168
|
-
if (payoutRecipient_ == address(0)) {
|
|
169
|
-
revert AddressZero();
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
// Set base contract state
|
|
173
|
-
__ERC20_init(name_, symbol_);
|
|
174
|
-
__ERC20Permit_init(name_);
|
|
175
|
-
__MultiOwnable_init(owners_);
|
|
176
|
-
__ReentrancyGuard_init();
|
|
107
|
+
super._initialize(payoutRecipient_, owners_, tokenURI_, name_, symbol_, platformReferrer_);
|
|
177
108
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
109
|
+
currency = currency_;
|
|
110
|
+
poolAddress = poolAddress_;
|
|
111
|
+
poolConfiguration = poolConfiguration_;
|
|
112
|
+
positions = positions_;
|
|
181
113
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
// Mint the total supply
|
|
186
|
-
_mint(address(this), MAX_TOTAL_SUPPLY);
|
|
114
|
+
CoinSetupV3.deployLiquidity(positions_, poolAddress);
|
|
115
|
+
}
|
|
187
116
|
|
|
188
|
-
|
|
189
|
-
|
|
117
|
+
function buildConfig() internal view returns (CoinConfig memory coinConfig) {
|
|
118
|
+
coinConfig = CoinConfig({
|
|
119
|
+
protocolRewardRecipient: protocolRewardRecipient,
|
|
120
|
+
platformReferrer: platformReferrer,
|
|
121
|
+
payoutRecipient: payoutRecipient,
|
|
122
|
+
protocolRewards: protocolRewards
|
|
123
|
+
});
|
|
124
|
+
}
|
|
190
125
|
|
|
191
|
-
|
|
192
|
-
|
|
126
|
+
function getPoolConfiguration() public view returns (PoolConfiguration memory) {
|
|
127
|
+
return poolConfiguration;
|
|
193
128
|
}
|
|
194
129
|
|
|
195
130
|
/// @notice Executes a buy order
|
|
@@ -204,37 +139,20 @@ contract Coin is ICoin, CoinConstants, ContractVersionBase, ERC20PermitUpgradeab
|
|
|
204
139
|
uint160 sqrtPriceLimitX96,
|
|
205
140
|
address tradeReferrer
|
|
206
141
|
) public payable nonReentrant returns (uint256, uint256) {
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
_handleIncomingCurrency(orderSize, trueOrderSize);
|
|
220
|
-
|
|
221
|
-
// Set up the swap parameters
|
|
222
|
-
ISwapRouter.ExactInputSingleParams memory params = ISwapRouter.ExactInputSingleParams({
|
|
223
|
-
tokenIn: currency,
|
|
224
|
-
tokenOut: address(this),
|
|
225
|
-
fee: MarketConstants.LP_FEE,
|
|
226
|
-
recipient: recipient,
|
|
227
|
-
amountIn: trueOrderSize,
|
|
228
|
-
amountOutMinimum: minAmountOut,
|
|
229
|
-
sqrtPriceLimitX96: sqrtPriceLimitX96
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
// Execute the swap
|
|
233
|
-
uint256 amountOut = ISwapRouter(swapRouter).exactInputSingle(params);
|
|
234
|
-
|
|
235
|
-
_handleTradeRewards(tradeReward, tradeReferrer);
|
|
142
|
+
CoinConfig memory coinConfig = buildConfig();
|
|
143
|
+
(uint256 amountOut, uint256 tradeReward, uint256 trueOrderSize) = UniV3BuySell.handleBuy(
|
|
144
|
+
recipient,
|
|
145
|
+
orderSize,
|
|
146
|
+
minAmountOut,
|
|
147
|
+
sqrtPriceLimitX96,
|
|
148
|
+
tradeReferrer,
|
|
149
|
+
coinConfig,
|
|
150
|
+
currency,
|
|
151
|
+
ISwapRouter(swapRouter),
|
|
152
|
+
IWETH(WETH)
|
|
153
|
+
);
|
|
236
154
|
|
|
237
|
-
|
|
155
|
+
UniV3BuySell.handleMarketRewards(coinConfig, currency, poolAddress, positions, IWETH(WETH), dopplerFeeRecipient());
|
|
238
156
|
|
|
239
157
|
emit CoinBuy(msg.sender, recipient, tradeReferrer, amountOut, currency, tradeReward, trueOrderSize);
|
|
240
158
|
|
|
@@ -254,11 +172,6 @@ contract Coin is ICoin, CoinConstants, ContractVersionBase, ERC20PermitUpgradeab
|
|
|
254
172
|
uint160 sqrtPriceLimitX96,
|
|
255
173
|
address tradeReferrer
|
|
256
174
|
) public nonReentrant returns (uint256, uint256) {
|
|
257
|
-
// Ensure the recipient is not the zero address
|
|
258
|
-
if (recipient == address(0)) {
|
|
259
|
-
revert AddressZero();
|
|
260
|
-
}
|
|
261
|
-
|
|
262
175
|
// Record the coin balance of this contract before the swap
|
|
263
176
|
uint256 beforeCoinBalance = balanceOf(address(this));
|
|
264
177
|
|
|
@@ -268,69 +181,33 @@ contract Coin is ICoin, CoinConstants, ContractVersionBase, ERC20PermitUpgradeab
|
|
|
268
181
|
// Approve the Uniswap V3 swap router
|
|
269
182
|
this.approve(swapRouter, orderSize);
|
|
270
183
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
// Record the coin balance of this contract after the swap
|
|
286
|
-
uint256 afterCoinBalance = balanceOf(address(this));
|
|
287
|
-
|
|
288
|
-
// If the swap was partially executed:
|
|
289
|
-
if (afterCoinBalance > beforeCoinBalance) {
|
|
290
|
-
// Calculate the refund
|
|
291
|
-
uint256 coinRefund = afterCoinBalance - beforeCoinBalance;
|
|
292
|
-
|
|
293
|
-
// Update the order size
|
|
294
|
-
orderSize -= coinRefund;
|
|
295
|
-
|
|
296
|
-
// Transfer the refund back to the seller
|
|
297
|
-
_transfer(address(this), recipient, coinRefund);
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
// If currency is WETH, convert to ETH
|
|
301
|
-
if (currency == WETH) {
|
|
302
|
-
IWETH(WETH).withdraw(amountOut);
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
// Calculate the trade reward
|
|
306
|
-
uint256 tradeReward = _calculateReward(amountOut, TOTAL_FEE_BPS);
|
|
307
|
-
|
|
308
|
-
// Calculate the payout after the fee
|
|
309
|
-
uint256 payoutSize = amountOut - tradeReward;
|
|
310
|
-
|
|
311
|
-
_handlePayout(payoutSize, recipient);
|
|
312
|
-
|
|
313
|
-
_handleTradeRewards(tradeReward, tradeReferrer);
|
|
314
|
-
|
|
315
|
-
_handleMarketRewards();
|
|
184
|
+
CoinConfig memory coinConfig = buildConfig();
|
|
185
|
+
|
|
186
|
+
SellResult memory result = UniV3BuySell.handleSell(
|
|
187
|
+
recipient,
|
|
188
|
+
beforeCoinBalance,
|
|
189
|
+
orderSize,
|
|
190
|
+
minAmountOut,
|
|
191
|
+
sqrtPriceLimitX96,
|
|
192
|
+
tradeReferrer,
|
|
193
|
+
coinConfig,
|
|
194
|
+
currency,
|
|
195
|
+
ISwapRouter(swapRouter),
|
|
196
|
+
IWETH(WETH)
|
|
197
|
+
);
|
|
316
198
|
|
|
317
|
-
|
|
199
|
+
UniV3BuySell.handleMarketRewards(coinConfig, currency, poolAddress, positions, IWETH(WETH), dopplerFeeRecipient());
|
|
318
200
|
|
|
319
|
-
|
|
320
|
-
}
|
|
201
|
+
emit ICoin.CoinSell(msg.sender, recipient, tradeReferrer, result.trueOrderSize, currency, result.tradeReward, result.payoutSize);
|
|
321
202
|
|
|
322
|
-
|
|
323
|
-
/// @param amount The amount of tokens to burn
|
|
324
|
-
function burn(uint256 amount) external {
|
|
325
|
-
// This burn function sets the from as msg.sender, so having an unauthed call is safe.
|
|
326
|
-
_burn(msg.sender, amount);
|
|
203
|
+
return (result.trueOrderSize, result.payoutSize);
|
|
327
204
|
}
|
|
328
205
|
|
|
329
206
|
/// @notice Force claim any accrued secondary rewards from the market's liquidity position.
|
|
330
207
|
/// @dev This function is a fallback, secondary rewards will be claimed automatically on each buy and sell.
|
|
331
208
|
/// @param pushEthRewards Whether to push the ETH directly to the recipients.
|
|
332
209
|
function claimSecondaryRewards(bool pushEthRewards) external nonReentrant {
|
|
333
|
-
MarketRewards memory rewards =
|
|
210
|
+
MarketRewards memory rewards = UniV3BuySell.handleMarketRewards(buildConfig(), currency, poolAddress, positions, IWETH(WETH), dopplerFeeRecipient());
|
|
334
211
|
|
|
335
212
|
if (pushEthRewards && rewards.totalAmountCurrency > 0 && currency == WETH) {
|
|
336
213
|
IProtocolRewards(protocolRewards).withdrawFor(payoutRecipient, rewards.creatorPayoutAmountCurrency);
|
|
@@ -339,314 +216,15 @@ contract Coin is ICoin, CoinConstants, ContractVersionBase, ERC20PermitUpgradeab
|
|
|
339
216
|
}
|
|
340
217
|
}
|
|
341
218
|
|
|
342
|
-
/// @notice Set the creator's payout address
|
|
343
|
-
/// @param newPayoutRecipient The new recipient address
|
|
344
|
-
function setPayoutRecipient(address newPayoutRecipient) external onlyOwner {
|
|
345
|
-
_setPayoutRecipient(newPayoutRecipient);
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
/// @notice Set the contract URI
|
|
349
|
-
/// @param newURI The new URI
|
|
350
|
-
function setContractURI(string memory newURI) external onlyOwner {
|
|
351
|
-
_setContractURI(newURI);
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
/// @notice The contract metadata
|
|
355
|
-
function contractURI() external view returns (string memory) {
|
|
356
|
-
return tokenURI;
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
/// @notice ERC165 interface support
|
|
360
|
-
/// @param interfaceId The interface ID to check
|
|
361
|
-
function supportsInterface(bytes4 interfaceId) public pure virtual returns (bool) {
|
|
362
|
-
return
|
|
363
|
-
interfaceId == type(ICoin).interfaceId ||
|
|
364
|
-
interfaceId == type(ICoinComments).interfaceId ||
|
|
365
|
-
interfaceId == type(IERC7572).interfaceId ||
|
|
366
|
-
interfaceId == type(IERC165).interfaceId;
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
/// @notice Receives ETH converted from WETH
|
|
370
|
-
receive() external payable {
|
|
371
|
-
require(msg.sender == WETH, OnlyWeth());
|
|
372
|
-
}
|
|
373
|
-
|
|
374
219
|
/// @dev Called by the pool after minting liquidity to transfer the associated coins
|
|
375
220
|
function uniswapV3MintCallback(uint256 amount0Owed, uint256 amount1Owed, bytes calldata) external {
|
|
376
|
-
if (msg.sender != poolAddress) revert OnlyPool();
|
|
221
|
+
if (msg.sender != poolAddress) revert OnlyPool(msg.sender, poolAddress);
|
|
377
222
|
|
|
378
223
|
IERC20(address(this)).safeTransfer(poolAddress, amount0Owed == 0 ? amount1Owed : amount0Owed);
|
|
379
224
|
}
|
|
380
225
|
|
|
381
|
-
/// @
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
emit CoinTransfer(from, to, value, balanceOf(from), balanceOf(to));
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
/// @dev Used to set the payout recipient on coin creation and updates
|
|
389
|
-
/// @param newPayoutRecipient The new recipient address
|
|
390
|
-
function _setPayoutRecipient(address newPayoutRecipient) internal {
|
|
391
|
-
if (newPayoutRecipient == address(0)) {
|
|
392
|
-
revert AddressZero();
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
emit CoinPayoutRecipientUpdated(msg.sender, payoutRecipient, newPayoutRecipient);
|
|
396
|
-
|
|
397
|
-
payoutRecipient = newPayoutRecipient;
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
/// @dev Used to set the contract URI on coin creation and updates
|
|
401
|
-
/// @param newURI The new URI
|
|
402
|
-
function _setContractURI(string memory newURI) internal {
|
|
403
|
-
emit ContractMetadataUpdated(msg.sender, newURI, name());
|
|
404
|
-
emit ContractURIUpdated();
|
|
405
|
-
|
|
406
|
-
tokenURI = newURI;
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
/// @dev Deploys the Uniswap V3 pool and mints initial liquidity based on the pool configuration
|
|
410
|
-
function _deployLiquidity(bytes memory poolConfig_) internal {
|
|
411
|
-
(uint8 version, address currency_) = abi.decode(poolConfig_, (uint8, address));
|
|
412
|
-
|
|
413
|
-
// Store the currency, defaulting to WETH if address(0)
|
|
414
|
-
currency = currency_ == address(0) ? WETH : currency_;
|
|
415
|
-
|
|
416
|
-
// Sort the token addresses
|
|
417
|
-
address token0 = address(this) < currency ? address(this) : currency;
|
|
418
|
-
address token1 = address(this) < currency ? currency : address(this);
|
|
419
|
-
bool isCoinToken0 = token0 == address(this);
|
|
420
|
-
|
|
421
|
-
(uint160 sqrtPriceX96, PoolConfiguration memory _poolConfig) = CoinSetup.setupPoolWithVersion(version, poolConfig_, isCoinToken0, WETH);
|
|
422
|
-
|
|
423
|
-
poolConfiguration = _poolConfig;
|
|
424
|
-
|
|
425
|
-
poolAddress = _createPool(token0, token1, sqrtPriceX96);
|
|
426
|
-
|
|
427
|
-
LpPosition[] memory positions = CoinSetup.calculatePositions(isCoinToken0, poolConfiguration);
|
|
428
|
-
|
|
429
|
-
_mintPositions(positions);
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
/// @dev Creates the Uniswap V3 pool for the coin/currency pair
|
|
433
|
-
function _createPool(address token0, address token1, uint160 sqrtPriceX96) internal returns (address pool) {
|
|
434
|
-
pool = IUniswapV3Factory(v3Factory).createPool(token0, token1, MarketConstants.LP_FEE);
|
|
435
|
-
|
|
436
|
-
// This pool should be new, if it has already been initialized
|
|
437
|
-
// then we will fail the creation step prompting the user to try again.
|
|
438
|
-
IUniswapV3Pool(pool).initialize(sqrtPriceX96);
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
/// @dev Mints the calculated liquidity positions into the Uniswap V3 pool
|
|
442
|
-
function _mintPositions(LpPosition[] memory lbpPositions) internal {
|
|
443
|
-
for (uint256 i; i < lbpPositions.length; i++) {
|
|
444
|
-
IUniswapV3Pool(poolAddress).mint(address(this), lbpPositions[i].tickLower, lbpPositions[i].tickUpper, lbpPositions[i].liquidity, "");
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
/// @dev Handles incoming currency transfers for buy orders; if WETH is the currency the caller has the option to send native-ETH
|
|
449
|
-
/// @param orderSize The total size of the order in the currency
|
|
450
|
-
/// @param trueOrderSize The actual amount being used for the swap after fees
|
|
451
|
-
function _handleIncomingCurrency(uint256 orderSize, uint256 trueOrderSize) internal {
|
|
452
|
-
if (currency == WETH && msg.value > 0) {
|
|
453
|
-
if (msg.value != orderSize) {
|
|
454
|
-
revert EthAmountMismatch();
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
if (msg.value < MIN_ORDER_SIZE) {
|
|
458
|
-
revert EthAmountTooSmall();
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
IWETH(WETH).deposit{value: trueOrderSize}();
|
|
462
|
-
IWETH(WETH).approve(swapRouter, trueOrderSize);
|
|
463
|
-
} else {
|
|
464
|
-
// Ensure ETH is not sent with a non-ETH pair
|
|
465
|
-
if (msg.value != 0) {
|
|
466
|
-
revert EthTransferInvalid();
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
uint256 beforeBalance = IERC20(currency).balanceOf(address(this));
|
|
470
|
-
IERC20(currency).safeTransferFrom(msg.sender, address(this), orderSize);
|
|
471
|
-
uint256 afterBalance = IERC20(currency).balanceOf(address(this));
|
|
472
|
-
|
|
473
|
-
if ((afterBalance - beforeBalance) != orderSize) {
|
|
474
|
-
revert ERC20TransferAmountMismatch();
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
IERC20(currency).approve(swapRouter, trueOrderSize);
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
/// @dev Handles sending ETH and ERC20 payouts and refunds to recipients
|
|
482
|
-
/// @param orderPayout The amount of currency to pay out
|
|
483
|
-
/// @param recipient The address to receive the payout
|
|
484
|
-
function _handlePayout(uint256 orderPayout, address recipient) internal {
|
|
485
|
-
if (currency == WETH) {
|
|
486
|
-
Address.sendValue(payable(recipient), orderPayout);
|
|
487
|
-
} else {
|
|
488
|
-
IERC20(currency).safeTransfer(recipient, orderPayout);
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
/// @dev Handles calculating and depositing fees to an escrow protocol rewards contract
|
|
493
|
-
function _handleTradeRewards(uint256 totalValue, address _tradeReferrer) internal {
|
|
494
|
-
if (_tradeReferrer == address(0)) {
|
|
495
|
-
_tradeReferrer = protocolRewardRecipient;
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
uint256 tokenCreatorFee = _calculateReward(totalValue, TOKEN_CREATOR_FEE_BPS);
|
|
499
|
-
uint256 platformReferrerFee = _calculateReward(totalValue, PLATFORM_REFERRER_FEE_BPS);
|
|
500
|
-
uint256 tradeReferrerFee = _calculateReward(totalValue, TRADE_REFERRER_FEE_BPS);
|
|
501
|
-
uint256 protocolFee = totalValue - tokenCreatorFee - platformReferrerFee - tradeReferrerFee;
|
|
502
|
-
|
|
503
|
-
if (currency == WETH) {
|
|
504
|
-
address[] memory recipients = new address[](4);
|
|
505
|
-
uint256[] memory amounts = new uint256[](4);
|
|
506
|
-
bytes4[] memory reasons = new bytes4[](4);
|
|
507
|
-
|
|
508
|
-
recipients[0] = payoutRecipient;
|
|
509
|
-
amounts[0] = tokenCreatorFee;
|
|
510
|
-
reasons[0] = bytes4(keccak256("COIN_CREATOR_REWARD"));
|
|
511
|
-
|
|
512
|
-
recipients[1] = platformReferrer;
|
|
513
|
-
amounts[1] = platformReferrerFee;
|
|
514
|
-
reasons[1] = bytes4(keccak256("COIN_PLATFORM_REFERRER_REWARD"));
|
|
515
|
-
|
|
516
|
-
recipients[2] = _tradeReferrer;
|
|
517
|
-
amounts[2] = tradeReferrerFee;
|
|
518
|
-
reasons[2] = bytes4(keccak256("COIN_TRADE_REFERRER_REWARD"));
|
|
519
|
-
|
|
520
|
-
recipients[3] = protocolRewardRecipient;
|
|
521
|
-
amounts[3] = protocolFee;
|
|
522
|
-
reasons[3] = bytes4(keccak256("COIN_PROTOCOL_REWARD"));
|
|
523
|
-
|
|
524
|
-
IProtocolRewards(protocolRewards).depositBatch{value: totalValue}(recipients, amounts, reasons, "");
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
if (currency != WETH) {
|
|
528
|
-
IERC20(currency).safeTransfer(payoutRecipient, tokenCreatorFee);
|
|
529
|
-
IERC20(currency).safeTransfer(platformReferrer, platformReferrerFee);
|
|
530
|
-
IERC20(currency).safeTransfer(_tradeReferrer, tradeReferrerFee);
|
|
531
|
-
IERC20(currency).safeTransfer(protocolRewardRecipient, protocolFee);
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
emit CoinTradeRewards(
|
|
535
|
-
payoutRecipient,
|
|
536
|
-
platformReferrer,
|
|
537
|
-
_tradeReferrer,
|
|
538
|
-
protocolRewardRecipient,
|
|
539
|
-
tokenCreatorFee,
|
|
540
|
-
platformReferrerFee,
|
|
541
|
-
tradeReferrerFee,
|
|
542
|
-
protocolFee,
|
|
543
|
-
currency
|
|
544
|
-
);
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
/// @dev Collects and distributes accrued fees from all LP positions
|
|
548
|
-
function _handleMarketRewards() internal returns (MarketRewards memory) {
|
|
549
|
-
uint256 totalAmountToken0;
|
|
550
|
-
uint256 totalAmountToken1;
|
|
551
|
-
uint256 amount0;
|
|
552
|
-
uint256 amount1;
|
|
553
|
-
|
|
554
|
-
bool isCoinToken0 = address(this) < currency;
|
|
555
|
-
LpPosition[] memory positions = CoinSetup.calculatePositions(isCoinToken0, poolConfiguration);
|
|
556
|
-
|
|
557
|
-
for (uint256 i; i < positions.length; i++) {
|
|
558
|
-
// Must burn to update the collect mapping on the pool
|
|
559
|
-
IUniswapV3Pool(poolAddress).burn(positions[i].tickLower, positions[i].tickUpper, 0);
|
|
560
|
-
|
|
561
|
-
(amount0, amount1) = IUniswapV3Pool(poolAddress).collect(
|
|
562
|
-
address(this),
|
|
563
|
-
positions[i].tickLower,
|
|
564
|
-
positions[i].tickUpper,
|
|
565
|
-
type(uint128).max,
|
|
566
|
-
type(uint128).max
|
|
567
|
-
);
|
|
568
|
-
|
|
569
|
-
totalAmountToken0 += amount0;
|
|
570
|
-
totalAmountToken1 += amount1;
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
address token0 = currency < address(this) ? currency : address(this);
|
|
574
|
-
address token1 = currency < address(this) ? address(this) : currency;
|
|
575
|
-
|
|
576
|
-
MarketRewards memory rewards;
|
|
577
|
-
|
|
578
|
-
rewards = _transferMarketRewards(token0, totalAmountToken0, rewards);
|
|
579
|
-
rewards = _transferMarketRewards(token1, totalAmountToken1, rewards);
|
|
580
|
-
|
|
581
|
-
emit CoinMarketRewards(payoutRecipient, platformReferrer, protocolRewardRecipient, currency, rewards);
|
|
582
|
-
|
|
583
|
-
return rewards;
|
|
584
|
-
}
|
|
585
|
-
|
|
586
|
-
function _transferMarketRewards(address token, uint256 totalAmount, MarketRewards memory rewards) internal returns (MarketRewards memory) {
|
|
587
|
-
if (totalAmount > 0) {
|
|
588
|
-
address dopplerRecipient = IAirlock(airlock).owner();
|
|
589
|
-
uint256 dopplerPayout = _calculateReward(totalAmount, DOPPLER_MARKET_REWARD_BPS);
|
|
590
|
-
uint256 creatorPayout = _calculateReward(totalAmount, CREATOR_MARKET_REWARD_BPS);
|
|
591
|
-
uint256 platformReferrerPayout = _calculateReward(totalAmount, PLATFORM_REFERRER_MARKET_REWARD_BPS);
|
|
592
|
-
uint256 protocolPayout = totalAmount - creatorPayout - platformReferrerPayout - dopplerPayout;
|
|
593
|
-
|
|
594
|
-
if (token == WETH) {
|
|
595
|
-
IWETH(WETH).withdraw(totalAmount);
|
|
596
|
-
|
|
597
|
-
rewards.totalAmountCurrency = totalAmount;
|
|
598
|
-
rewards.creatorPayoutAmountCurrency = creatorPayout;
|
|
599
|
-
rewards.platformReferrerAmountCurrency = platformReferrerPayout;
|
|
600
|
-
rewards.protocolAmountCurrency = protocolPayout;
|
|
601
|
-
|
|
602
|
-
address[] memory recipients = new address[](4);
|
|
603
|
-
recipients[0] = payoutRecipient;
|
|
604
|
-
recipients[1] = platformReferrer;
|
|
605
|
-
recipients[2] = protocolRewardRecipient;
|
|
606
|
-
recipients[3] = dopplerRecipient;
|
|
607
|
-
|
|
608
|
-
uint256[] memory amounts = new uint256[](4);
|
|
609
|
-
amounts[0] = rewards.creatorPayoutAmountCurrency;
|
|
610
|
-
amounts[1] = rewards.platformReferrerAmountCurrency;
|
|
611
|
-
amounts[2] = rewards.protocolAmountCurrency;
|
|
612
|
-
amounts[3] = dopplerPayout;
|
|
613
|
-
|
|
614
|
-
bytes4[] memory reasons = new bytes4[](4);
|
|
615
|
-
reasons[0] = bytes4(keccak256("COIN_CREATOR_MARKET_REWARD"));
|
|
616
|
-
reasons[1] = bytes4(keccak256("COIN_PLATFORM_REFERRER_MARKET_REWARD"));
|
|
617
|
-
reasons[2] = bytes4(keccak256("COIN_PROTOCOL_MARKET_REWARD"));
|
|
618
|
-
reasons[3] = bytes4(keccak256("COIN_DOPPLER_MARKET_REWARD"));
|
|
619
|
-
|
|
620
|
-
IProtocolRewards(protocolRewards).depositBatch{value: totalAmount}(recipients, amounts, reasons, "");
|
|
621
|
-
IProtocolRewards(protocolRewards).withdrawFor(dopplerRecipient, dopplerPayout);
|
|
622
|
-
} else if (token == address(this)) {
|
|
623
|
-
rewards.totalAmountCoin = totalAmount;
|
|
624
|
-
rewards.creatorPayoutAmountCoin = creatorPayout;
|
|
625
|
-
rewards.platformReferrerAmountCoin = platformReferrerPayout;
|
|
626
|
-
rewards.protocolAmountCoin = protocolPayout;
|
|
627
|
-
|
|
628
|
-
_transfer(address(this), payoutRecipient, rewards.creatorPayoutAmountCoin);
|
|
629
|
-
_transfer(address(this), platformReferrer, rewards.platformReferrerAmountCoin);
|
|
630
|
-
_transfer(address(this), protocolRewardRecipient, rewards.protocolAmountCoin);
|
|
631
|
-
_transfer(address(this), dopplerRecipient, dopplerPayout);
|
|
632
|
-
} else {
|
|
633
|
-
rewards.totalAmountCurrency = totalAmount;
|
|
634
|
-
rewards.creatorPayoutAmountCurrency = creatorPayout;
|
|
635
|
-
rewards.platformReferrerAmountCurrency = platformReferrerPayout;
|
|
636
|
-
rewards.protocolAmountCurrency = protocolPayout;
|
|
637
|
-
|
|
638
|
-
IERC20(currency).safeTransfer(payoutRecipient, creatorPayout);
|
|
639
|
-
IERC20(currency).safeTransfer(platformReferrer, platformReferrerPayout);
|
|
640
|
-
IERC20(currency).safeTransfer(protocolRewardRecipient, protocolPayout);
|
|
641
|
-
IERC20(currency).safeTransfer(dopplerRecipient, dopplerPayout);
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
|
|
645
|
-
return rewards;
|
|
646
|
-
}
|
|
647
|
-
|
|
648
|
-
/// @dev Utility for computing amounts in basis points.
|
|
649
|
-
function _calculateReward(uint256 amount, uint256 bps) internal pure returns (uint256) {
|
|
650
|
-
return (amount * bps) / 10_000;
|
|
226
|
+
/// @notice Receives ETH converted from WETH
|
|
227
|
+
receive() external payable {
|
|
228
|
+
require(msg.sender == WETH, OnlyWeth());
|
|
651
229
|
}
|
|
652
230
|
}
|