generated from uniswapfoundation/v4-template
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCounter.sol
133 lines (110 loc) · 5.15 KB
/
Counter.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import {BaseHook} from "v4-periphery/src/base/hooks/BaseHook.sol";
import {Hooks} from "v4-core/src/libraries/Hooks.sol";
import {IPoolManager} from "v4-core/src/interfaces/IPoolManager.sol";
import {PoolKey} from "v4-core/src/types/PoolKey.sol";
import {PoolId, PoolIdLibrary} from "v4-core/src/types/PoolId.sol";
import {BalanceDelta} from "v4-core/src/types/BalanceDelta.sol";
import {BeforeSwapDelta, BeforeSwapDeltaLibrary, toBeforeSwapDelta} from "v4-core/src/types/BeforeSwapDelta.sol";
import {Currency, CurrencyLibrary} from "v4-core/src/types/Currency.sol";
import {SafeCast} from "v4-core/src/libraries/SafeCast.sol";
// Make sure to update the interface when Stylus Contract's Solidity ABI changes.
interface IUniswapCurve {
function getAmountInForExactOutput(uint256 amountOut, address input, address output, bool zeroForOne)
external
returns (uint256);
function getAmountOutFromExactInput(uint256 amountIn, address input, address output, bool zeroForOne)
external
returns (uint256);
}
contract Counter is BaseHook {
using PoolIdLibrary for PoolKey;
using CurrencyLibrary for Currency;
using SafeCast for uint256;
// NOTE: ---------------------------------------------------------
// state variables should typically be unique to a pool
// a single hook contract should be able to service multiple pools
// ---------------------------------------------------------------
mapping(PoolId => uint256 count) public beforeSwapCount;
mapping(PoolId => uint256 count) public afterSwapCount;
mapping(PoolId => uint256 count) public beforeAddLiquidityCount;
mapping(PoolId => uint256 count) public beforeRemoveLiquidityCount;
IUniswapCurve _curveContract;
constructor(IPoolManager _poolManager, address _curveContractAddress) BaseHook(_poolManager) {
_curveContract = IUniswapCurve(_curveContractAddress);
}
function getHookPermissions() public pure override returns (Hooks.Permissions memory) {
return Hooks.Permissions({
beforeInitialize: false,
afterInitialize: false,
beforeAddLiquidity: true,
afterAddLiquidity: false,
beforeRemoveLiquidity: true,
afterRemoveLiquidity: false,
beforeSwap: true, // -- Custom Curve Handler -- //
afterSwap: true,
beforeDonate: false,
afterDonate: false,
beforeSwapReturnDelta: false, // -- Enable Custom Curves here if needed -- //
afterSwapReturnDelta: false,
afterAddLiquidityReturnDelta: false,
afterRemoveLiquidityReturnDelta: false
});
}
// -----------------------------------------------
// NOTE: see IHooks.sol for function documentation
// -----------------------------------------------
function beforeSwap(address, PoolKey calldata key, IPoolManager.SwapParams calldata params, bytes calldata)
external
override
returns (bytes4, BeforeSwapDelta, uint24)
{
// You can add, modify, or delete the logic here if needed.
bool exactInput = params.amountSpecified < 0;
(Currency specified, Currency unspecified) =
(params.zeroForOne == exactInput) ? (key.currency0, key.currency1) : (key.currency1, key.currency0);
uint256 specifiedAmount = exactInput ? uint256(-params.amountSpecified) : uint256(params.amountSpecified);
uint256 unspecifiedAmount;
BeforeSwapDelta returnDelta;
if (exactInput) {
unspecifiedAmount = _curveContract.getAmountOutFromExactInput(
specifiedAmount, Currency.unwrap(specified), Currency.unwrap(unspecified), params.zeroForOne
);
returnDelta = toBeforeSwapDelta(specifiedAmount.toInt128(), -unspecifiedAmount.toInt128());
} else {
unspecifiedAmount = _curveContract.getAmountInForExactOutput(
specifiedAmount, Currency.unwrap(unspecified), Currency.unwrap(specified), params.zeroForOne
);
returnDelta = toBeforeSwapDelta(-specifiedAmount.toInt128(), unspecifiedAmount.toInt128());
}
beforeSwapCount[key.toId()]++;
return (BaseHook.beforeSwap.selector, returnDelta, 0);
}
function afterSwap(address, PoolKey calldata key, IPoolManager.SwapParams calldata, BalanceDelta, bytes calldata)
external
override
returns (bytes4, int128)
{
afterSwapCount[key.toId()]++;
return (BaseHook.afterSwap.selector, 0);
}
function beforeAddLiquidity(
address,
PoolKey calldata key,
IPoolManager.ModifyLiquidityParams calldata,
bytes calldata
) external override returns (bytes4) {
beforeAddLiquidityCount[key.toId()]++;
return BaseHook.beforeAddLiquidity.selector;
}
function beforeRemoveLiquidity(
address,
PoolKey calldata key,
IPoolManager.ModifyLiquidityParams calldata,
bytes calldata
) external override returns (bytes4) {
beforeRemoveLiquidityCount[key.toId()]++;
return BaseHook.beforeRemoveLiquidity.selector;
}
}