-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #21 from uniswapfoundation/msg.sender
Access msg.sender
- Loading branch information
Showing
14 changed files
with
613 additions
and
1 deletion.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.19; | ||
|
||
import "forge-std/Test.sol"; | ||
import {IHooks} from "v4-core/interfaces/IHooks.sol"; | ||
import {Hooks} from "v4-core/libraries/Hooks.sol"; | ||
import {TickMath} from "v4-core/libraries/TickMath.sol"; | ||
import {IPoolManager} from "v4-core/interfaces/IPoolManager.sol"; | ||
import {PoolSwapTest} from "v4-core/test/PoolSwapTest.sol"; | ||
import {PoolKey} from "v4-core/types/PoolKey.sol"; | ||
import {BalanceDelta} from "v4-core/types/BalanceDelta.sol"; | ||
import {PoolId, PoolIdLibrary} from "v4-core/types/PoolId.sol"; | ||
import {Constants} from "v4-core/../test/utils/Constants.sol"; | ||
import {CurrencyLibrary, Currency} from "v4-core/types/Currency.sol"; | ||
import {HookTest} from "@v4-by-example/utils/HookTest.sol"; | ||
import {GetCurrentLockCaller} from "src/pages/hooks/msg-sender/GetCurrentLockCaller.sol"; | ||
import {HookMiner} from "./utils/HookMiner.sol"; | ||
|
||
contract GetCurrentLockCallerTest is HookTest { | ||
using PoolIdLibrary for PoolKey; | ||
using CurrencyLibrary for Currency; | ||
|
||
GetCurrentLockCaller counter; | ||
PoolKey poolKey; | ||
PoolId poolId; | ||
|
||
address alice = makeAddr("alice"); | ||
|
||
function setUp() public { | ||
// creates the pool manager, test tokens, and other utility routers | ||
HookTest.initHookTestEnv(); | ||
|
||
// Deploy the hook to an address with the correct flags | ||
uint160 flags = uint160(Hooks.BEFORE_SWAP_FLAG); | ||
(address hookAddress, bytes32 salt) = | ||
HookMiner.find(address(this), flags, type(GetCurrentLockCaller).creationCode, abi.encode(address(manager))); | ||
counter = new GetCurrentLockCaller{salt: salt}(IPoolManager(address(manager))); | ||
require(address(counter) == hookAddress, "GetCurrentLockCallerTest: hook address mismatch"); | ||
|
||
// Create the pool | ||
poolKey = PoolKey(Currency.wrap(address(token0)), Currency.wrap(address(token1)), 3000, 60, IHooks(counter)); | ||
poolId = poolKey.toId(); | ||
initializeRouter.initialize(poolKey, Constants.SQRT_RATIO_1_1, ZERO_BYTES); | ||
|
||
// Provide liquidity to the pool | ||
modifyPositionRouter.modifyLiquidity(poolKey, IPoolManager.ModifyLiquidityParams(-60, 60, 10 ether), ZERO_BYTES); | ||
modifyPositionRouter.modifyLiquidity( | ||
poolKey, IPoolManager.ModifyLiquidityParams(-120, 120, 10 ether), ZERO_BYTES | ||
); | ||
modifyPositionRouter.modifyLiquidity( | ||
poolKey, | ||
IPoolManager.ModifyLiquidityParams(TickMath.minUsableTick(60), TickMath.maxUsableTick(60), 10 ether), | ||
ZERO_BYTES | ||
); | ||
} | ||
|
||
function test_getCurrentLockCaller() public { | ||
counter.setAllowedUser(alice, true); | ||
token0.mint(alice, 100 ether); | ||
|
||
vm.startPrank(alice); | ||
token0.approve(address(swapRouter), type(uint256).max); | ||
|
||
// Perform a test swap // | ||
int256 amount = 1e18; | ||
bool zeroForOne = true; | ||
lockSwap(poolKey, amount, zeroForOne, ZERO_BYTES, false); | ||
// ------------------- // | ||
vm.stopPrank(); | ||
} | ||
|
||
function test_getCurrentLockCallerRevert() public { | ||
counter.setAllowedUser(alice, false); | ||
token0.mint(alice, 100 ether); | ||
|
||
vm.startPrank(alice); | ||
token0.approve(address(swapRouter), type(uint256).max); | ||
|
||
// Perform a test swap // | ||
int256 amount = 1e18; | ||
bool zeroForOne = true; | ||
vm.expectRevert(); | ||
lockSwap(poolKey, amount, zeroForOne, ZERO_BYTES, true); | ||
// ------------------- // | ||
vm.stopPrank(); | ||
} | ||
|
||
function lockSwap( | ||
PoolKey memory key, | ||
int256 amountSpecified, | ||
bool zeroForOne, | ||
bytes memory hookData, | ||
bool expectRevert | ||
) internal returns (BalanceDelta swapDelta) { | ||
IPoolManager.SwapParams memory params = IPoolManager.SwapParams({ | ||
zeroForOne: zeroForOne, | ||
amountSpecified: amountSpecified, | ||
sqrtPriceLimitX96: zeroForOne ? MIN_PRICE_LIMIT : MAX_PRICE_LIMIT // unlimited impact | ||
}); | ||
|
||
PoolSwapTest.TestSettings memory testSettings = | ||
PoolSwapTest.TestSettings({withdrawTokens: true, settleUsingTransfer: true, currencyAlreadySent: false}); | ||
|
||
bytes memory result; | ||
if (expectRevert) { | ||
vm.expectRevert(); | ||
result = manager.lock( | ||
address(swapRouter), | ||
abi.encode(PoolSwapTest.CallbackData(address(this), testSettings, key, params, hookData)) | ||
); | ||
} else { | ||
result = manager.lock( | ||
address(swapRouter), | ||
abi.encode(PoolSwapTest.CallbackData(address(this), testSettings, key, params, hookData)) | ||
); | ||
} | ||
|
||
swapDelta = abi.decode(result, (BalanceDelta)); | ||
} | ||
} |
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,86 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.19; | ||
|
||
import "forge-std/Test.sol"; | ||
import {IHooks} from "v4-core/interfaces/IHooks.sol"; | ||
import {Hooks} from "v4-core/libraries/Hooks.sol"; | ||
import {TickMath} from "v4-core/libraries/TickMath.sol"; | ||
import {IPoolManager} from "v4-core/interfaces/IPoolManager.sol"; | ||
import {PoolKey} from "v4-core/types/PoolKey.sol"; | ||
import {BalanceDelta} from "v4-core/types/BalanceDelta.sol"; | ||
import {PoolId, PoolIdLibrary} from "v4-core/types/PoolId.sol"; | ||
import {Constants} from "v4-core/../test/utils/Constants.sol"; | ||
import {CurrencyLibrary, Currency} from "v4-core/types/Currency.sol"; | ||
import {HookTest} from "@v4-by-example/utils/HookTest.sol"; | ||
import {MsgSenderHookData} from "src/pages/hooks/msg-sender/MsgSenderHookData.sol"; | ||
import {HookMiner} from "./utils/HookMiner.sol"; | ||
|
||
contract MsgSenderHookDataTest is HookTest { | ||
using PoolIdLibrary for PoolKey; | ||
using CurrencyLibrary for Currency; | ||
|
||
MsgSenderHookData counter; | ||
PoolKey poolKey; | ||
PoolId poolId; | ||
|
||
address alice = makeAddr("alice"); | ||
|
||
function setUp() public { | ||
// creates the pool manager, test tokens, and other utility routers | ||
HookTest.initHookTestEnv(); | ||
|
||
// Deploy the hook to an address with the correct flags | ||
uint160 flags = uint160(Hooks.BEFORE_SWAP_FLAG); | ||
(address hookAddress, bytes32 salt) = | ||
HookMiner.find(address(this), flags, type(MsgSenderHookData).creationCode, abi.encode(address(manager))); | ||
counter = new MsgSenderHookData{salt: salt}(IPoolManager(address(manager))); | ||
require(address(counter) == hookAddress, "MsgSenderHookDataTest: hook address mismatch"); | ||
|
||
// Create the pool | ||
poolKey = PoolKey(Currency.wrap(address(token0)), Currency.wrap(address(token1)), 3000, 60, IHooks(counter)); | ||
poolId = poolKey.toId(); | ||
initializeRouter.initialize(poolKey, Constants.SQRT_RATIO_1_1, ZERO_BYTES); | ||
|
||
// Provide liquidity to the pool | ||
modifyPositionRouter.modifyLiquidity(poolKey, IPoolManager.ModifyLiquidityParams(-60, 60, 10 ether), ZERO_BYTES); | ||
modifyPositionRouter.modifyLiquidity( | ||
poolKey, IPoolManager.ModifyLiquidityParams(-120, 120, 10 ether), ZERO_BYTES | ||
); | ||
modifyPositionRouter.modifyLiquidity( | ||
poolKey, | ||
IPoolManager.ModifyLiquidityParams(TickMath.minUsableTick(60), TickMath.maxUsableTick(60), 10 ether), | ||
ZERO_BYTES | ||
); | ||
} | ||
|
||
function test_msgSenderHookData() public { | ||
counter.setAllowedUser(alice, true); | ||
token0.mint(alice, 100 ether); | ||
|
||
vm.startPrank(alice); | ||
token0.approve(address(swapRouter), type(uint256).max); | ||
|
||
// Perform a test swap // | ||
int256 amount = 1e18; | ||
bool zeroForOne = true; | ||
swap(poolKey, amount, zeroForOne, abi.encode(alice)); | ||
// ------------------- // | ||
vm.stopPrank(); | ||
} | ||
|
||
function test_msgSenderRevert() public { | ||
counter.setAllowedUser(alice, false); | ||
token0.mint(alice, 100 ether); | ||
|
||
vm.startPrank(alice); | ||
token0.approve(address(swapRouter), type(uint256).max); | ||
|
||
// Perform a test swap // | ||
int256 amount = 1e18; | ||
bool zeroForOne = true; | ||
vm.expectRevert(); | ||
swap(poolKey, amount, zeroForOne, abi.encode(alice)); | ||
// ------------------- // | ||
vm.stopPrank(); | ||
} | ||
} |
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
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,51 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.19; | ||
|
||
// TODO: update to v4-periphery/BaseHook.sol when its compatible | ||
import {BaseHook} from "@v4-by-example/utils/BaseHook.sol"; | ||
|
||
import {console2} from "forge-std/console2.sol"; | ||
import {Hooks} from "v4-core/libraries/Hooks.sol"; | ||
import {IPoolManager} from "v4-core/interfaces/IPoolManager.sol"; | ||
import {PoolKey} from "v4-core/types/PoolKey.sol"; | ||
import {BalanceDelta} from "v4-core/types/BalanceDelta.sol"; | ||
import {Lockers} from "v4-core/libraries/Lockers.sol"; | ||
|
||
contract GetCurrentLockCaller is BaseHook { | ||
mapping(address user => bool allowed) public allowedUsers; | ||
|
||
constructor(IPoolManager _poolManager) BaseHook(_poolManager) {} | ||
|
||
function beforeSwap(address, PoolKey calldata key, IPoolManager.SwapParams calldata, bytes calldata hookData) | ||
external | ||
override | ||
returns (bytes4) | ||
{ | ||
// --- Read the user's address --- // | ||
(, address user) = poolManager.getLock(1); | ||
require(allowedUsers[user], "GetCurrentLockCaller: User not allowed"); | ||
return BaseHook.beforeSwap.selector; | ||
} | ||
|
||
// Helper function for demonstration | ||
function setAllowedUser(address user, bool allowed) external { | ||
allowedUsers[user] = allowed; | ||
} | ||
|
||
function getHookPermissions() public pure override returns (Hooks.Permissions memory) { | ||
return Hooks.Permissions({ | ||
beforeInitialize: false, | ||
afterInitialize: false, | ||
beforeAddLiquidity: false, | ||
beforeRemoveLiquidity: false, | ||
afterAddLiquidity: false, | ||
afterRemoveLiquidity: false, | ||
beforeSwap: true, | ||
afterSwap: false, | ||
beforeDonate: false, | ||
afterDonate: false, | ||
noOp: false, | ||
accessLock: false | ||
}); | ||
} | ||
} |
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,52 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.19; | ||
|
||
// TODO: update to v4-periphery/BaseHook.sol when its compatible | ||
import {BaseHook} from "@v4-by-example/utils/BaseHook.sol"; | ||
|
||
import {Hooks} from "v4-core/libraries/Hooks.sol"; | ||
import {IPoolManager} from "v4-core/interfaces/IPoolManager.sol"; | ||
import {PoolKey} from "v4-core/types/PoolKey.sol"; | ||
import {PoolId, PoolIdLibrary} from "v4-core/types/PoolId.sol"; | ||
import {BalanceDelta} from "v4-core/types/BalanceDelta.sol"; | ||
|
||
contract MsgSenderHookData is BaseHook { | ||
using PoolIdLibrary for PoolKey; | ||
|
||
mapping(address user => bool allowed) public allowedUsers; | ||
|
||
constructor(IPoolManager _poolManager) BaseHook(_poolManager) {} | ||
|
||
function beforeSwap(address, PoolKey calldata key, IPoolManager.SwapParams calldata, bytes calldata hookData) | ||
external | ||
override | ||
returns (bytes4) | ||
{ | ||
// --- Read the user's address --- // | ||
address user = abi.decode(hookData, (address)); | ||
require(allowedUsers[user], "MsgSenderHookData: User not allowed"); | ||
return BaseHook.beforeSwap.selector; | ||
} | ||
|
||
// Helper function for demonstration | ||
function setAllowedUser(address user, bool allowed) external { | ||
allowedUsers[user] = allowed; | ||
} | ||
|
||
function getHookPermissions() public pure override returns (Hooks.Permissions memory) { | ||
return Hooks.Permissions({ | ||
beforeInitialize: false, | ||
afterInitialize: false, | ||
beforeAddLiquidity: false, | ||
beforeRemoveLiquidity: false, | ||
afterAddLiquidity: false, | ||
afterRemoveLiquidity: false, | ||
beforeSwap: true, | ||
afterSwap: false, | ||
beforeDonate: false, | ||
afterDonate: false, | ||
noOp: false, | ||
accessLock: false | ||
}); | ||
} | ||
} |
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,7 @@ | ||
// User directly locks on the PoolManager | ||
// - poolManager.getLock(1) returns alice's address | ||
vm.prank(alice); | ||
manager.lock( | ||
address(swapRouter), | ||
abi.encode(PoolSwapTest.CallbackData(address(this), testSettings, key, params, hookData)) | ||
); |
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,7 @@ | ||
IPoolManager.SwapParams memory params = ...; | ||
|
||
PoolSwapTest.TestSettings memory testSettings = ...; | ||
|
||
// provide the user's address as hookData to be available inside the hook function | ||
bytes memory hookData = abi.encode(address(USER_ADDRESS)); | ||
swapRouter.swap(key, params, testSettings, hookData); |
Oops, something went wrong.