Address Contract Verified
Address
0x1C7FAf18a4Ceb2eA10F27538E940681Dd02C99D4
Balance
0 ETH
Nonce
1
Code Size
4498 bytes
Creator
0xde091fc5...81F6 at tx 0x2b2894fa...fbb54f
Indexed Transactions
0
Contract Bytecode
4498 bytes
0x60806040526004361061007f5760003560e01c8063920f5c841161004e578063920f5c841461012a578063ad5c46481461015a578063e9240c2d14610182578063fe94df88146101a257600080fd5b806351cff8d91461008b5780636065c245146100ad578063735de9f7146100cd5780638da5cb5b1461010a57600080fd5b3661008657005b600080fd5b34801561009757600080fd5b506100ab6100a6366004610cfe565b6101d6565b005b3480156100b957600080fd5b506100ab6100c8366004610d22565b61030f565b3480156100d957600080fd5b506002546100ed906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561011657600080fd5b506001546100ed906001600160a01b031681565b34801561013657600080fd5b5061014a610145366004610d9a565b6104fe565b6040519015158152602001610101565b34801561016657600080fd5b506100ed73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b34801561018e57600080fd5b506003546100ed906001600160a01b031681565b3480156101ae57600080fd5b506100ed7f00000000000000000000000087870bca3f3fd6335c3f4ce8392d69350b4fa4e281565b6001546001600160a01b031633146102265760405162461bcd60e51b815260206004820152600e60248201526d139bdd08185d5d1a1bdc9a5e995960921b60448201526064015b60405180910390fd5b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa15801561026d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102919190610e9f565b60015460405163a9059cbb60e01b81526001600160a01b0391821660048201526024810183905291925083169063a9059cbb906044016020604051808303816000875af11580156102e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061030a9190610eb8565b505050565b6001546001600160a01b0316331461035a5760405162461bcd60e51b815260206004820152600e60248201526d139bdd08185d5d1a1bdc9a5e995960921b604482015260640161021d565b604080516001808252818301909252600091602080830190803683375050604080516001808252818301909252929350600092915060208083019080368337505060408051600180825281830190925292935060009291506020808301908036833701905050905084836000815181106103d6576103d6610ef0565b60200260200101906001600160a01b031690816001600160a01b031681525050838260008151811061040a5761040a610ef0565b60200260200101818152505060008160008151811061042b5761042b610ef0565b6020026020010181815250507f00000000000000000000000087870bca3f3fd6335c3f4ce8392d69350b4fa4e26001600160a01b031663ab9c4b5d30858585308b8b6040516020016104929291906001600160a01b03929092168252602082015260400190565b60405160208183030381529060405260006040518863ffffffff1660e01b81526004016104c59796959493929190610f7a565b600060405180830381600087803b1580156104df57600080fd5b505af11580156104f3573d6000803e3d6000fd5b505050505050505050565b6000336001600160a01b037f00000000000000000000000087870bca3f3fd6335c3f4ce8392d69350b4fa4e216146105785760405162461bcd60e51b815260206004820152601b60248201527f43616c6c6572206d757374206265206c656e64696e6720706f6f6c0000000000604482015260640161021d565b6001600160a01b03841630146105d05760405162461bcd60e51b815260206004820152601f60248201527f496e69746961746f72206d757374206265207468697320636f6e747261637400604482015260640161021d565b60008a8a60008181106105e5576105e5610ef0565b90506020020160208101906105fa9190610cfe565b905060008989600081811061061157610611610ef0565b90506020020135905060008888600081811061062f5761062f610ef0565b905060200201359050600080878781019061064a9190610d22565b91509150816001600160a01b0316856001600160a01b0316146106a05760405162461bcd60e51b815260206004820152600e60248201526d082e6e6cae840dad2e6dac2e8c6d60931b604482015260640161021d565b8084146106e15760405162461bcd60e51b815260206004820152600f60248201526e082dadeeadce840dad2e6dac2e8c6d608b1b604482015260640161021d565b60408051606080825260139082015272119b185cda081b1bd85b881c9958d95a5d9959606a1b60808201526001600160a01b03871660208201529081018590527fb515f8464a2e9f92f223836cb4d97889b194249a3f5a6bae6b346c6b0ac8fd559060a00160405180910390a1604080516002808252606082018352600092602083019080368337019050509050858160008151811061078357610783610ef0565b60200260200101906001600160a01b031690816001600160a01b03168152505073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2816001815181106107cb576107cb610ef0565b6001600160a01b03928316602091820292909201015260025460405163095ea7b360e01b81529082166004820152602481018790529087169063095ea7b3906044016020604051808303816000875af115801561082c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108509190610eb8565b506002546001600160a01b03166338ed173986600084306108734261012c611042565b6040518663ffffffff1660e01b815260040161089395949392919061105b565b6000604051808303816000875af11580156108b2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526108da9190810190611097565b5060408051600280825260608201835260009260208301908036833701905050905073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28160008151811061092457610924610ef0565b60200260200101906001600160a01b031690816001600160a01b031681525050868160018151811061095857610958610ef0565b6001600160a01b0392909216602092830291909101909101526040516370a0823160e01b815230600482015260009073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2906370a0823190602401602060405180830381865afa1580156109c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109e79190610e9f565b60035460405163095ea7b360e01b81526001600160a01b0390911660048201526024810182905290915073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc29063095ea7b3906044016020604051808303816000875af1158015610a4f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a739190610eb8565b506003546001600160a01b03166338ed17398260008530610a964261012c611042565b6040518663ffffffff1660e01b8152600401610ab695949392919061105b565b6000604051808303816000875af1158015610ad5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610afd9190810190611097565b506000610b0a8789611042565b6040516370a0823160e01b81523060048201529091506000906001600160a01b038b16906370a0823190602401602060405180830381865afa158015610b54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b789190610e9f565b905081811015610bdb5760405162461bcd60e51b815260206004820152602860248201527f496e73756666696369656e742062616c616e636520746f20726570617920666c60448201526730b9b4103637b0b760c11b606482015260840161021d565b60405163095ea7b360e01b81526001600160a01b037f00000000000000000000000087870bca3f3fd6335c3f4ce8392d69350b4fa4e281166004830152602482018490528b169063095ea7b3906044016020604051808303816000875af1158015610c4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c6e9190610eb8565b506000610c7b8383611149565b90508e6001600160a01b03168b6001600160a01b03167f639acc6deb763ca53e1967f8d03e7bab23716b7eda3dc2908a798b2784c8e53183604051610cc291815260200190565b60405180910390a360019b5050505050505050505050509998505050505050505050565b6001600160a01b0381168114610cfb57600080fd5b50565b600060208284031215610d1057600080fd5b8135610d1b81610ce6565b9392505050565b60008060408385031215610d3557600080fd5b8235610d4081610ce6565b946020939093013593505050565b60008083601f840112610d6057600080fd5b50813567ffffffffffffffff811115610d7857600080fd5b6020830191508360208260051b8501011115610d9357600080fd5b9250929050565b600080600080600080600080600060a08a8c031215610db857600080fd5b893567ffffffffffffffff80821115610dd057600080fd5b610ddc8d838e01610d4e565b909b50995060208c0135915080821115610df557600080fd5b610e018d838e01610d4e565b909950975060408c0135915080821115610e1a57600080fd5b610e268d838e01610d4e565b909750955060608c01359150610e3b82610ce6565b90935060808b01359080821115610e5157600080fd5b818c0191508c601f830112610e6557600080fd5b813581811115610e7457600080fd5b8d6020828501011115610e8657600080fd5b6020830194508093505050509295985092959850929598565b600060208284031215610eb157600080fd5b5051919050565b600060208284031215610eca57600080fd5b81518015158114610d1b57600080fd5b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b600081518084526020808501945080840160005b83811015610f3f5781516001600160a01b031687529582019590820190600101610f1a565b509495945050505050565b600081518084526020808501945080840160005b83811015610f3f57815187529582019590820190600101610f5e565b600060018060a01b03808a168352602060e081850152610f9d60e085018b610f06565b8481036040860152610faf818b610f4a565b90508481036060860152610fc3818a610f4a565b92881660808601525083820360a085015285518083529160005b83811015610ff8578781018301518282018401528201610fdd565b506000818401830152601f909201601f191690910101905061102060c083018461ffff169052565b98975050505050505050565b634e487b7160e01b600052601160045260246000fd5b808201808211156110555761105561102c565b92915050565b85815284602082015260a06040820152600061107a60a0830186610f06565b6001600160a01b0394909416606083015250608001529392505050565b600060208083850312156110aa57600080fd5b825167ffffffffffffffff808211156110c257600080fd5b818501915085601f8301126110d657600080fd5b8151818111156110e8576110e8610eda565b8060051b604051601f19603f8301168101818110858211171561110d5761110d610eda565b60405291825284820192508381018501918883111561112b57600080fd5b938501935b8285101561102057845184529385019392850192611130565b818103818111156110555761105561102c56fea264697066735822122060b94adbbc763ff8d5e197a0995473f48896efa79e646cef74a06a488b11f92064736f6c63430008140033
Verified Source Code Full Match
Compiler: v0.8.20+commit.a1b79de6
EVM: paris
Optimization: Yes (200 runs)
FlashLoanArbitrage.sol 156 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
interface IUniswapV2Router {
function swapExactTokensForTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external returns (uint[] memory amounts);
}
interface IPool {
function flashLoan(
address receiverAddress,
address[] calldata assets,
uint256[] calldata amounts,
uint256[] calldata modes,
address onBehalfOf,
bytes calldata params,
uint16 referralCode
) external;
}
contract FlashLoanArbitrage is ReentrancyGuard {
address public owner;
address public immutable POOL_ADDRESS;
address public uniswapRouter;
address public sushiswapRouter;
address public constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
event DebugLog(string message, address asset, uint256 amount);
event ArbitrageExecuted(address indexed asset, uint256 profit, address indexed initiator);
constructor(address _poolAddress, address _uniswapRouter, address _sushiswapRouter) {
owner = msg.sender;
POOL_ADDRESS = _poolAddress;
uniswapRouter = _uniswapRouter;
sushiswapRouter = _sushiswapRouter;
}
function executeFlashLoan(
address asset,
uint256 amount
) external {
require(msg.sender == owner, "Not authorized");
// Declare arrays for flash loan parameters
address[] memory assets = new address[](1);
uint256[] memory amounts = new uint256[](1);
uint256[] memory modes = new uint256[](1);
assets[0] = asset;
amounts[0] = amount;
modes[0] = 0; // No debt mode, full repayment expected
IPool(POOL_ADDRESS).flashLoan(
address(this),
assets,
amounts,
modes,
address(this),
abi.encode(asset, amount),
0
);
}
function executeOperation(
address[] calldata assets,
uint256[] calldata amounts,
uint256[] calldata premiums,
address initiator,
bytes calldata params
) external returns (bool) {
require(msg.sender == POOL_ADDRESS, "Caller must be lending pool");
require(initiator == address(this), "Initiator must be this contract");
// Extract the borrowed asset and amount
address asset = assets[0];
uint256 amount = amounts[0];
uint256 premium = premiums[0];
// Decode parameters
(address borrowedAsset, uint256 borrowedAmount) = abi.decode(params, (address, uint256));
require(asset == borrowedAsset, "Asset mismatch");
require(amount == borrowedAmount, "Amount mismatch");
emit DebugLog("Flash loan received", asset, amount);
// Create path for Uniswap swap (asset → WETH)
address[] memory uniswapPath = new address[](2);
uniswapPath[0] = asset;
uniswapPath[1] = WETH;
// Approve Uniswap router to spend our tokens
IERC20(asset).approve(uniswapRouter, amount);
// Execute swap on Uniswap (asset → WETH)
IUniswapV2Router(uniswapRouter).swapExactTokensForTokens(
amount,
0, // Accept any amount
uniswapPath,
address(this),
block.timestamp + 300
);
// Create path for SushiSwap swap (WETH → asset)
address[] memory sushiswapPath = new address[](2);
sushiswapPath[0] = WETH;
sushiswapPath[1] = asset;
// Get WETH balance
uint256 wethBalance = IERC20(WETH).balanceOf(address(this));
// Approve SushiSwap router to spend our WETH
IERC20(WETH).approve(sushiswapRouter, wethBalance);
// Execute swap on SushiSwap (WETH → asset)
IUniswapV2Router(sushiswapRouter).swapExactTokensForTokens(
wethBalance,
0, // Accept any amount
sushiswapPath,
address(this),
block.timestamp + 300
);
// Calculate amount to repay (initial amount + premium)
uint256 amountToRepay = amount + premium;
// Check if arbitrage was profitable
uint256 finalBalance = IERC20(asset).balanceOf(address(this));
require(finalBalance >= amountToRepay, "Insufficient balance to repay flash loan");
// Approve the lending pool to pull the owed amount
IERC20(asset).approve(POOL_ADDRESS, amountToRepay);
// Calculate profit
uint256 profit = finalBalance - amountToRepay;
emit ArbitrageExecuted(asset, profit, initiator);
return true;
}
function withdraw(address token) external {
require(msg.sender == owner, "Not authorized");
uint256 balance = IERC20(token).balanceOf(address(this));
IERC20(token).transfer(owner, balance);
}
// Function to receive ETH
receive() external payable {}
}
IERC20.sol 79 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC-20 standard as defined in the ERC.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 value) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 value) external returns (bool);
}
ReentrancyGuard.sol 87 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/ReentrancyGuard.sol)
pragma solidity ^0.8.20;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If EIP-1153 (transient storage) is available on the chain you're deploying at,
* consider using {ReentrancyGuardTransient} instead.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant NOT_ENTERED = 1;
uint256 private constant ENTERED = 2;
uint256 private _status;
/**
* @dev Unauthorized reentrant call.
*/
error ReentrancyGuardReentrantCall();
constructor() {
_status = NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, _status will be NOT_ENTERED
if (_status == ENTERED) {
revert ReentrancyGuardReentrantCall();
}
// Any calls to nonReentrant after this point will fail
_status = ENTERED;
}
function _nonReentrantAfter() private {
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = NOT_ENTERED;
}
/**
* @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
* `nonReentrant` function in the call stack.
*/
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == ENTERED;
}
}
Read Contract
POOL_ADDRESS 0xfe94df88 → address
WETH 0xad5c4648 → address
owner 0x8da5cb5b → address
sushiswapRouter 0xe9240c2d → address
uniswapRouter 0x735de9f7 → address
Write Contract 3 functions
These functions modify contract state and require a wallet transaction to execute.
executeFlashLoan 0x6065c245
address asset
uint256 amount
executeOperation 0x920f5c84
address[] assets
uint256[] amounts
uint256[] premiums
address initiator
bytes params
returns: bool
withdraw 0x51cff8d9
address token
Recent Transactions
No transactions found for this address