chore: OneTransferFromOnly docs + proper slots
Also revert instead of returning if multiple `transferFrom`s are attempted - as this signals that encoding is incorrect or has been messed with.
This commit is contained in:
@@ -5,24 +5,42 @@ import "@interfaces/IExecutor.sol";
|
|||||||
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
||||||
import "@permit2/src/interfaces/IAllowanceTransfer.sol";
|
import "@permit2/src/interfaces/IAllowanceTransfer.sol";
|
||||||
|
|
||||||
error TokenTransfer__AddressZero();
|
error OneTransferFromOnly__AddressZero();
|
||||||
|
error OneTransferFromOnly__MultipleTransferFrom();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @title OneTransferFromOnly - Restrict to one transferFrom on approved params per swap
|
||||||
|
* @author PropellerHeads Devs
|
||||||
|
* @dev Restricts to one `transferFrom` (using `permit2` or regular `transferFrom`)
|
||||||
|
* per swap, while ensuring that the `transferFrom` is only performed on the input
|
||||||
|
* token and the input amount, from the msg.sender's wallet that calls the main swap
|
||||||
|
* method. Reverts if multiple `transferFrom`s are attempted.
|
||||||
|
*/
|
||||||
contract OneTransferFromOnly {
|
contract OneTransferFromOnly {
|
||||||
using SafeERC20 for IERC20;
|
using SafeERC20 for IERC20;
|
||||||
|
|
||||||
// this is a stupid name but the compiler was complaining that we already had a permit2 variable in TychoRouter
|
IAllowanceTransfer public immutable permit2;
|
||||||
IAllowanceTransfer public immutable permit2lal;
|
// keccak256("Dispatcher#TOKEN_IN_SLOT")
|
||||||
uint256 private constant _TOKEN_IN_SLOT = 123;
|
uint256 private constant _TOKEN_IN_SLOT =
|
||||||
uint256 private constant _AMOUNT_IN_SLOT = 124;
|
0x66f353cfe8e3cbe0d03292348fbf0fca32e6e07fa0c2a52b4aac22193ac3b894;
|
||||||
uint256 private constant _IS_PERMIT2_SLOT = 125;
|
// keccak256("Dispatcher#AMOUNT_IN_SLOT")
|
||||||
uint256 private constant _SENDER_SLOT = 126;
|
uint256 private constant _AMOUNT_IN_SLOT =
|
||||||
uint256 private constant _IS_TRANSFER_EXECUTED_SLOT = 127;
|
0x1f40aa2d23d66d03722685ce02e5d3a95545dfc8e7c56d1026790aa30be48937;
|
||||||
|
// keccak256("Dispatcher#IS_PERMIT2_SLOT")
|
||||||
|
uint256 private constant _IS_PERMIT2_SLOT =
|
||||||
|
0x3162c9d1175ca0ca7441f87984fdac41bbfdb13246f42c8bb4414d345da39e2a;
|
||||||
|
// keccak256("Dispatcher#SENDER_SLOT")
|
||||||
|
uint256 private constant _SENDER_SLOT =
|
||||||
|
0x5dcc7974be5cb30f183f878073999aaa6620995b9e052ab5a713071ff60ae9b5;
|
||||||
|
// keccak256("Dispatcher#IS_TRANSFER_EXECUTED_SLOT")
|
||||||
|
uint256 private constant _IS_TRANSFER_EXECUTED_SLOT =
|
||||||
|
0x1c64085c839fc2ff0f0aad20613eb6d056a1024e5990211e9eb30824dcd128c2;
|
||||||
|
|
||||||
constructor(address _permit2) {
|
constructor(address _permit2) {
|
||||||
if (_permit2 == address(0)) {
|
if (_permit2 == address(0)) {
|
||||||
revert TokenTransfer__AddressZero();
|
revert OneTransferFromOnly__AddressZero();
|
||||||
}
|
}
|
||||||
permit2lal = IAllowanceTransfer(_permit2);
|
permit2 = IAllowanceTransfer(_permit2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// slither-disable-next-line assembly
|
// slither-disable-next-line assembly
|
||||||
@@ -56,12 +74,12 @@ contract OneTransferFromOnly {
|
|||||||
isTransferExecuted := tload(_IS_TRANSFER_EXECUTED_SLOT)
|
isTransferExecuted := tload(_IS_TRANSFER_EXECUTED_SLOT)
|
||||||
}
|
}
|
||||||
if (isTransferExecuted) {
|
if (isTransferExecuted) {
|
||||||
return; // or revert?
|
revert OneTransferFromOnly__MultipleTransferFrom();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isPermit2) {
|
if (isPermit2) {
|
||||||
// Permit2.permit is already called from the TychoRouter
|
// Permit2.permit is already called from the TychoRouter
|
||||||
permit2lal.transferFrom(sender, receiver, uint160(amount), tokenIn);
|
permit2.transferFrom(sender, receiver, uint160(amount), tokenIn);
|
||||||
assembly {
|
assembly {
|
||||||
tstore(_IS_TRANSFER_EXECUTED_SLOT, true)
|
tstore(_IS_TRANSFER_EXECUTED_SLOT, true)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,7 +73,6 @@ contract TychoRouter is
|
|||||||
ReentrancyGuard,
|
ReentrancyGuard,
|
||||||
OneTransferFromOnly
|
OneTransferFromOnly
|
||||||
{
|
{
|
||||||
IAllowanceTransfer public immutable permit2;
|
|
||||||
IWETH private immutable _weth;
|
IWETH private immutable _weth;
|
||||||
|
|
||||||
using SafeERC20 for IERC20;
|
using SafeERC20 for IERC20;
|
||||||
|
|||||||
Reference in New Issue
Block a user