Description:
Multi-signature wallet contract requiring multiple confirmations for transaction execution.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
{{
"language": "Solidity",
"sources": {
"FlashLoanReceiver.sol": {
"content": "// SPDX-License-Identifier: MIT\r
pragma solidity ^0.8.17;\r
\r
/*\r
Gelişmiş Aave v3 FlashLoan Receiver (FlashLoanSimple)\r
- Arbitraj stratejisi entegre edilmiş\r
- Güvenlik iyileştirmeleri\r
- Çoklu DEX desteği\r
*/\r
\r
interface IERC20 {\r
function approve(address spender, uint256 amount) external returns (bool);\r
function balanceOf(address who) external view returns (uint256);\r
function transfer(address to, uint256 value) external returns (bool);\r
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\r
function decimals() external view returns (uint8);\r
}\r
\r
interface ILendingPool {\r
function flashLoanSimple(\r
address receiverAddress,\r
address asset,\r
uint256 amount,\r
bytes calldata params,\r
uint16 referralCode\r
) external;\r
}\r
\r
// Aave v3 FlashLoan Simple Receiver Interface\r
interface IFlashLoanSimpleReceiver {\r
function executeOperation(\r
address asset,\r
uint256 amount,\r
uint256 premium,\r
address initiator,\r
bytes calldata params\r
) external returns (bool);\r
}\r
\r
// Uniswap V2 Router Interface\r
interface IUniswapV2Router {\r
function swapExactTokensForTokens(\r
uint amountIn,\r
uint amountOutMin,\r
address[] calldata path,\r
address to,\r
uint deadline\r
) external returns (uint[] memory amounts);\r
\r
function swapTokensForExactTokens(\r
uint amountOut,\r
uint amountInMax,\r
address[] calldata path,\r
address to,\r
uint deadline\r
) external returns (uint[] memory amounts);\r
\r
function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);\r
function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);\r
function WETH() external pure returns (address);\r
}\r
\r
contract FlashLoanReceiver is IFlashLoanSimpleReceiver {\r
address public owner;\r
ILendingPool public lendingPool;\r
\r
// Arbitraj için DEX router'ları\r
address public uniswapRouter;\r
address public sushiswapRouter;\r
\r
// Events\r
event FlashLoanExecuted(\r
address indexed asset, \r
uint256 amount, \r
uint256 premium, \r
uint256 profit,\r
bool success\r
);\r
event ArbitrageTrade(\r
address indexed buyDex,\r
address indexed sellDex,\r
uint256 amountIn,\r
uint256 amountOut,\r
uint256 profit\r
);\r
event EmergencyStop(bool stopped);\r
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\r
\r
// Güvenlik modları\r
bool public emergencyStop;\r
mapping(address => bool) public authorizedCallers;\r
\r
modifier onlyOwner() {\r
require(msg.sender == owner, "Only owner");\r
_;\r
}\r
\r
modifier onlyAuthorized() {\r
require(msg.sender == owner || authorizedCallers[msg.sender], "Not authorized");\r
_;\r
}\r
\r
modifier notStopped() {\r
require(!emergencyStop, "Contract stopped");\r
_;\r
}\r
\r
constructor(\r
address _lendingPool,\r
address _uniswapRouter,\r
address _sushiswapRouter\r
) {\r
require(_lendingPool != address(0), "Invalid lendingPool");\r
require(_uniswapRouter != address(0), "Invalid Uniswap router");\r
require(_sushiswapRouter != address(0), "Invalid SushiSwap router");\r
\r
owner = msg.sender;\r
lendingPool = ILendingPool(_lendingPool);\r
uniswapRouter = _uniswapRouter;\r
sushiswapRouter = _sushiswapRouter;\r
\r
authorizedCallers[msg.sender] = true;\r
}\r
\r
/**\r
* @notice Flash loan başlatma fonksiyonu\r
* @param asset Ödünç alınacak token adresi\r
* @param amount Ödünç alınacak miktar\r
* @param buyDex Alış yapılacak DEX router adresi\r
* @param sellDex Satış yapılacak DEX router adresi \r
* @param path Token swap yolu\r
* @param minProfit Minimum kâr threshold'u (wei cinsinden)\r
*/\r
function initiateFlashLoan(\r
address asset,\r
uint256 amount,\r
address buyDex,\r
address sellDex,\r
address[] calldata path,\r
uint256 minProfit\r
) external onlyAuthorized notStopped {\r
require(amount > 0, "Amount must be > 0");\r
require(path.length >= 2, "Invalid path");\r
require(buyDex != sellDex, "DEX addresses must be different");\r
\r
// Parametreleri encode et\r
bytes memory params = abi.encode(\r
buyDex,\r
sellDex,\r
path,\r
minProfit,\r
msg.sender\r
);\r
\r
uint16 referralCode = 0;\r
lendingPool.flashLoanSimple(address(this), asset, amount, params, referralCode);\r
}\r
\r
/**\r
* @notice Aave tarafından çağrılan flash loan execution fonksiyonu\r
*/\r
function executeOperation(\r
address asset,\r
uint256 amount,\r
uint256 premium,\r
address initiator,\r
bytes calldata params\r
) external override returns (bool) {\r
// Güvenlik kontrolleri\r
require(msg.sender == address(lendingPool), "Caller must be LendingPool");\r
require(initiator == address(this), "Initiator must be this contract");\r
require(!emergencyStop, "Contract is stopped");\r
\r
// Parametreleri decode et\r
(\r
address buyDex,\r
address sellDex, \r
address[] memory path,\r
uint256 minProfit,\r
address originalCaller\r
) = abi.decode(params, (address, address, address[], uint256, address));\r
\r
// Arbitraj stratejisini çalıştır\r
uint256 profit = _executeArbitrage(\r
asset,\r
amount,\r
premium,\r
buyDex,\r
sellDex,\r
path,\r
minProfit\r
);\r
\r
// Aave'e geri ödeme için approve\r
uint256 totalDebt = amount + premium;\r
_safeApprove(asset, address(lendingPool), totalDebt);\r
\r
// Kârı original caller'a gönder (opsiyonel)\r
if (profit > 0 && originalCaller != address(this)) {\r
uint256 callerShare = profit * 10 / 100; // %10 komisyon\r
if (callerShare > 0) {\r
_safeTransfer(asset, originalCaller, callerShare);\r
profit -= callerShare;\r
}\r
}\r
\r
emit FlashLoanExecuted(asset, amount, premium, profit, true);\r
return true;\r
}\r
\r
/**\r
* @notice Arbitraj stratejisini yürüt\r
*/\r
function _executeArbitrage(\r
address asset,\r
uint256 amount,\r
uint256 premium,\r
address buyDex,\r
address sellDex,\r
address[] memory path,\r
uint256 minProfit\r
) internal returns (uint256) {\r
require(path[0] == asset, "First token in path must be loan asset");\r
\r
// 1. Adım: Alış DEX'inde token swap\r
_safeApprove(asset, buyDex, amount);\r
\r
uint256[] memory buyAmounts = IUniswapV2Router(buyDex).swapExactTokensForTokens(\r
amount,\r
0, // Minimum output (slippage kontrolü için daha güvenli değer kullanılabilir)\r
path,\r
address(this),\r
block.timestamp + 300\r
);\r
\r
uint256 intermediateAmount = buyAmounts[buyAmounts.length - 1];\r
emit ArbitrageTrade(buyDex, sellDex, amount, intermediateAmount, 0);\r
\r
// 2. Adım: Satış DEX'inde ters swap\r
address[] memory reversePath = _reversePath(path);\r
\r
_safeApprove(path[path.length - 1], sellDex, intermediateAmount);\r
\r
uint256[] memory sellAmounts = IUniswapV2Router(sellDex).swapExactTokensForTokens(\r
intermediateAmount,\r
0, // Minimum output\r
reversePath,\r
address(this),\r
block.timestamp + 300\r
);\r
\r
uint256 finalAmount = sellAmounts[sellAmounts.length - 1];\r
\r
// 3. Adım: Kâr hesapla\r
uint256 totalDebt = amount + premium;\r
require(finalAmount >= totalDebt, "Insufficient final amount");\r
\r
uint256 profit = finalAmount - totalDebt;\r
require(profit >= minProfit, "Profit below minimum threshold");\r
\r
emit ArbitrageTrade(sellDex, buyDex, intermediateAmount, finalAmount, profit);\r
\r
return profit;\r
}\r
\r
/**\r
* @notice Swap yolunu tersine çevir\r
*/\r
function _reversePath(address[] memory path) internal pure returns (address[] memory) {\r
address[] memory reversed = new address[](path.length);\r
for (uint i = 0; i < path.length; i++) {\r
reversed[i] = path[path.length - 1 - i];\r
}\r
return reversed;\r
}\r
\r
/**\r
* @notice Güvenli token approve\r
*/\r
function _safeApprove(address token, address spender, uint256 amount) internal {\r
(bool success, ) = token.call(\r
abi.encodeWithSignature("approve(address,uint256)", spender, amount)\r
);\r
require(success, "Approve failed");\r
}\r
\r
/**\r
* @notice Güvenli token transfer\r
*/\r
function _safeTransfer(address token, address to, uint256 amount) internal {\r
(bool success, ) = token.call(\r
abi.encodeWithSignature("transfer(address,uint256)", to, amount)\r
);\r
require(success, "Transfer failed");\r
}\r
\r
// === YÖNETİM FONKSİYONLARI ===\r
\r
/**\r
* @notice Acil durdurma\r
*/\r
function setEmergencyStop(bool stopped) external onlyOwner {\r
emergencyStop = stopped;\r
emit EmergencyStop(stopped);\r
}\r
\r
/**\r
* @notice Yetkili caller ekle/çıkar\r
*/\r
function setAuthorizedCaller(address caller, bool authorized) external onlyOwner {\r
authorizedCallers[caller] = authorized;\r
}\r
\r
/**\r
* @notice Owner değiştir\r
*/\r
function transferOwnership(address newOwner) external onlyOwner {\r
require(newOwner != address(0), "Invalid owner");\r
emit OwnershipTransferred(owner, newOwner);\r
owner = newOwner;\r
}\r
\r
/**\r
* @notice Lending pool adresini güncelle\r
*/\r
function setLendingPool(address _lendingPool) external onlyOwner {\r
require(_lendingPool != address(0), "Invalid lendingPool");\r
lendingPool = ILendingPool(_lendingPool);\r
}\r
\r
/**\r
* @notice DEX router adreslerini güncelle\r
*/\r
function setRouters(address _uniswapRouter, address _sushiswapRouter) external onlyOwner {\r
require(_uniswapRouter != address(0), "Invalid Uniswap router");\r
require(_sushiswapRouter != address(0), "Invalid SushiSwap router");\r
uniswapRouter = _uniswapRouter;\r
sushiswapRouter = _sushiswapRouter;\r
}\r
\r
/**\r
* @notice Kontrattaki token'ları kurtar\r
*/\r
function rescueTokens(address token, address to, uint256 amount) external onlyOwner {\r
require(to != address(0), "Invalid recipient");\r
_safeTransfer(token, to, amount);\r
}\r
\r
/**\r
* @notice Kontrattaki ETH'i kurtar\r
*/\r
function rescueETH(address payable to, uint256 amount) external onlyOwner {\r
require(to != address(0), "Invalid recipient");\r
require(address(this).balance >= amount, "Insufficient balance");\r
to.transfer(amount);\r
}\r
\r
/**\r
* @notice Token bakiyesini görüntüle\r
*/\r
function getBalance(address token) external view returns (uint256) {\r
return IERC20(token).balanceOf(address(this));\r
}\r
\r
/**\r
* @notice Kontratın ETH bakiyesi\r
*/\r
function getETHBalance() external view returns (uint256) {\r
return address(this).balance;\r
}\r
\r
// Fallback fonksiyonları\r
receive() external payable {}\r
fallback() external payable {}\r
}"
}
},
"settings": {
"optimizer": {
"enabled": false,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"remappings": []
}
}}
Submitted on: 2025-10-29 10:18:31
Comments
Log in to comment.
No comments yet.