-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
388 additions
and
96 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Submodule v4-periphery
added at
1394ff
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,57 +1,57 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.24; | ||
|
||
import { ISwapRouter } from "@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol"; | ||
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; | ||
|
||
import { ClvrIntentPool } from "./ClvrIntentPool.sol"; | ||
import { ClvrLibrary } from "./ClvrLibrary.sol"; | ||
|
||
contract ClvrExecutor { | ||
ClvrIntentPool private intentPool; | ||
ISwapRouter private swapRouter; | ||
|
||
constructor(address intentPool_, address swapRouter_) { | ||
intentPool = ClvrIntentPool(intentPool_); | ||
swapRouter = ISwapRouter(swapRouter_); | ||
} | ||
|
||
/** | ||
* @notice Execute a batch of intents | ||
* @param statusQuoPrice The starting price TODO: get this in contract | ||
* @param poolKey The identifier for the pool through which the intents are being executed | ||
* @param intents The intents to execute | ||
*/ | ||
function executeBatch(uint256 statusQuoPrice, bytes32 poolKey, ClvrLibrary.CLVRIntent[] memory intents) public { | ||
// uint256[] memory volumes = new uint256[](intents.length); | ||
for (uint256 i = 0; i < intents.length; i++) { | ||
bytes32 intentHash = keccak256(abi.encode(intents[i])); | ||
|
||
bytes4 verification = intentPool.intentExists(poolKey, intentHash); | ||
|
||
if (verification != ClvrLibrary.MAGICVALUE) { | ||
revert("Invalid Intent Passed to Executor"); | ||
} | ||
} | ||
} | ||
|
||
function executeIntent(ClvrLibrary.CLVRIntent memory intent) private { | ||
IERC20(intent.tokenIn).transferFrom(intent.creator, address(this), intent.amountIn); | ||
IERC20(intent.tokenIn).approve(address(swapRouter), intent.amountIn); | ||
|
||
uint256 amountOut = swapRouter.exactInputSingle(ISwapRouter.ExactInputSingleParams({ | ||
tokenIn: intent.tokenIn, | ||
tokenOut: intent.tokenOut, | ||
fee: intent.fee, | ||
recipient: intent.recipient, | ||
deadline: block.timestamp, | ||
amountIn: intent.amountIn, | ||
amountOutMinimum: 0, | ||
sqrtPriceLimitX96: 0 | ||
})); | ||
|
||
IERC20(intent.tokenOut).transfer(intent.recipient, amountOut); | ||
|
||
// emit IntentExecuted(intent.creator, intent.tokenIn, intent.tokenOut, intent.recipient, intent.fee, intent.amountIn, amountOut); | ||
} | ||
} | ||
// // SPDX-License-Identifier: MIT | ||
// pragma solidity ^0.8.24; | ||
|
||
// import { ISwapRouter } from "@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol"; | ||
// import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; | ||
|
||
// import { ClvrIntentPool } from "./ClvrIntentPool.sol"; | ||
// import { ClvrLibrary } from "./ClvrLibrary.sol"; | ||
|
||
// contract ClvrExecutor { | ||
// ClvrIntentPool private intentPool; | ||
// ISwapRouter private swapRouter; | ||
|
||
// constructor(address intentPool_, address swapRouter_) { | ||
// intentPool = ClvrIntentPool(intentPool_); | ||
// swapRouter = ISwapRouter(swapRouter_); | ||
// } | ||
|
||
// /** | ||
// * @notice Execute a batch of intents | ||
// * @param statusQuoPrice The starting price TODO: get this in contract | ||
// * @param poolKey The identifier for the pool through which the intents are being executed | ||
// * @param intents The intents to execute | ||
// */ | ||
// function executeBatch(uint256 statusQuoPrice, bytes32 poolKey, ClvrLibrary.CLVRIntent[] memory intents) public { | ||
// // uint256[] memory volumes = new uint256[](intents.length); | ||
// for (uint256 i = 0; i < intents.length; i++) { | ||
// bytes32 intentHash = keccak256(abi.encode(intents[i])); | ||
|
||
// bytes4 verification = intentPool.intentExists(poolKey, intentHash); | ||
|
||
// if (verification != ClvrLibrary.MAGICVALUE) { | ||
// revert("Invalid Intent Passed to Executor"); | ||
// } | ||
// } | ||
// } | ||
|
||
// function executeIntent(ClvrLibrary.CLVRIntent memory intent) private { | ||
// IERC20(intent.tokenIn).transferFrom(intent.creator, address(this), intent.amountIn); | ||
// IERC20(intent.tokenIn).approve(address(swapRouter), intent.amountIn); | ||
|
||
// uint256 amountOut = swapRouter.exactInputSingle(ISwapRouter.ExactInputSingleParams({ | ||
// tokenIn: intent.tokenIn, | ||
// tokenOut: intent.tokenOut, | ||
// fee: intent.fee, | ||
// recipient: intent.recipient, | ||
// deadline: block.timestamp, | ||
// amountIn: intent.amountIn, | ||
// amountOutMinimum: 0, | ||
// sqrtPriceLimitX96: 0 | ||
// })); | ||
|
||
// IERC20(intent.tokenOut).transfer(intent.recipient, amountOut); | ||
|
||
// // emit IntentExecuted(intent.creator, intent.tokenIn, intent.tokenOut, intent.recipient, intent.fee, intent.amountIn, amountOut); | ||
// } | ||
// } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.24; | ||
|
||
import {BaseHook} from "@uniswap/v4-periphery/src/base/hooks/BaseHook.sol"; | ||
|
||
import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol"; | ||
import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; | ||
import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; | ||
import {PoolId, PoolIdLibrary} from "@uniswap/v4-core/src/types/PoolId.sol"; | ||
import {BalanceDelta} from "@uniswap/v4-core/src/types/BalanceDelta.sol"; | ||
import {BeforeSwapDelta, BeforeSwapDeltaLibrary} from "@uniswap/v4-core/src/types/BeforeSwapDelta.sol"; | ||
import {Currency} from "@uniswap/v4-core/src/types/Currency.sol"; | ||
import {SafeCast} from "@uniswap/v4-core/src/libraries/SafeCast.sol"; | ||
|
||
import { ClvrIntentPool } from "./ClvrIntentPool.sol"; | ||
import { ClvrModel } from "./ClvrModel.sol"; | ||
|
||
|
||
contract ClvrHook is BaseHook { | ||
using SafeCast for *; | ||
|
||
struct SwapParamsExtended { | ||
address recepient; | ||
IPoolManager.SwapParams params; | ||
} | ||
|
||
mapping(PoolId => SwapParamsExtended[]) public swapParams; | ||
ClvrModel private model; | ||
|
||
constructor(IPoolManager _manager) BaseHook(_manager) {} | ||
|
||
function getHookPermissions() | ||
public | ||
pure | ||
virtual | ||
override | ||
returns (Hooks.Permissions memory) | ||
{ | ||
return Hooks.Permissions({ | ||
beforeInitialize: false, | ||
afterInitialize: false, | ||
beforeAddLiquidity: false, | ||
afterAddLiquidity: false, | ||
beforeRemoveLiquidity: false, | ||
afterRemoveLiquidity: false, | ||
beforeSwap: true, | ||
afterSwap: false, | ||
beforeDonate: true, | ||
afterDonate: false, | ||
beforeSwapReturnDelta: false, | ||
afterSwapReturnDelta: false, | ||
afterAddLiquidityReturnDelta: false, | ||
afterRemoveLiquidityReturnDelta: false | ||
}); | ||
} | ||
|
||
function beforeSwap(address, PoolKey calldata key, IPoolManager.SwapParams calldata params, bytes calldata data) | ||
external | ||
override | ||
returns (bytes4, BeforeSwapDelta, uint24) | ||
{ | ||
require(params.amountSpecified < 0, "Clvr Pools only work with exact input swaps"); | ||
|
||
PoolId poolId = PoolIdLibrary.toId(key); | ||
|
||
Currency input = params.zeroForOne ? key.currency0 : key.currency1; | ||
uint256 amountTaken = uint256(params.amountSpecified); | ||
poolManager.mint(address(this), input.toId(), amountTaken); | ||
|
||
address recepient = abi.decode(data, (address)); | ||
|
||
SwapParamsExtended memory paramsE = SwapParamsExtended({ | ||
recepient: recepient, | ||
params: params | ||
}); | ||
|
||
// Store the swap params | ||
swapParams[poolId].push(paramsE); | ||
|
||
return (BaseHook.beforeSwap.selector, BeforeSwapDeltaLibrary.ZERO_DELTA, 0); | ||
} | ||
|
||
function beforeDonate(address, PoolKey calldata key, uint256, uint256, bytes calldata) | ||
external | ||
override | ||
returns (bytes4) | ||
{ | ||
PoolId poolId = key.toId(); | ||
|
||
SwapParamsExtended[] memory params = swapParams[poolId]; | ||
if (params.length == 0) { | ||
return BaseHook.beforeDonate.selector; | ||
} | ||
|
||
// ClvrModel.TradeMinimal[] memory trades = swapParamsToTradeMinimalArrays(params); | ||
|
||
|
||
} | ||
|
||
// function swapParamsToTradeMinimalArrays(SwapParamsExtended[] memory params) internal view returns (ClvrModel.TradeMinimal[] memory) { | ||
// ClvrModel.TradeMinimal[] memory tradeMinimals = new ClvrModel.TradeMinimal[](params.length); | ||
|
||
// // append null trade at the beginning | ||
// tradeMinimals[0] = ClvrModel.TradeMinimal({ | ||
// direction: ClvrModel.Direction.NULL, | ||
// amountIn: 0 | ||
// }); | ||
|
||
// for (uint256 i = 0; i < params.length; i++) { | ||
// tradeMinimals[i + 1] = swapParamsToTradeMinimal(params[i]); | ||
// } | ||
// return tradeMinimals; | ||
// } | ||
|
||
// function swapParamsToTradeMinimal(SwapParamsExtended memory params) internal view returns (ClvrModel.TradeMinimal memory) { | ||
// return ClvrModel.TradeMinimal({ | ||
// direction: params.params.zeroForOne ? ClvrModel.Direction.Buy : ClvrModel.Direction.Sell, | ||
// amountIn: uint256(-params.params.amountSpecified) | ||
// }); | ||
// } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.24; | ||
|
||
import { ln } from "@prb-math/ud60x18/Math.sol"; | ||
import { UD60x18, ud } from "@prb-math/UD60x18.sol"; | ||
import { console } from "forge-std/console.sol"; | ||
|
||
import { ClvrIntentPool } from "./ClvrIntentPool.sol"; | ||
|
||
// NOT AN ACTUAL NATURAL LOG | ||
library ClvrLn { | ||
// ln only takes >1e18 uints, hence use property: | ||
// ln(a) = ln(a * 1e18 / 1e18) = ln(a * 1e18) - ln(1e18) | ||
function lnU256(uint256 x) public pure returns (uint256) { | ||
uint256 appendedX = x * 1e18; | ||
uint256 natlog1e18 = ln(ud(appendedX)).unwrap(); | ||
return natlog1e18; | ||
} | ||
} | ||
|
Oops, something went wrong.