Transactions
Token Transfers
Tokens
Internal Transactions
Coin Balance History
Logs
Code
Read Contract
Write Contract
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
This contract has been partially verified via Sourcify.
View contract in Sourcify repository
- Contract name:
- SushiMaker
- Optimization enabled
- true
- Compiler version
- v0.6.12+commit.27d51765
- Optimization runs
- 5000
- EVM Version
- istanbul
- Verified at
- 2026-03-30T11:58:16.960424Z
Constructor Arguments
000000000000000000000000c0aee478e3658e2610c5f7a4a2e1777ce9e4f2ac0000000000000000000000008798249c2e607446efb7ad49ec89dd1865ff42720000000000000000000000006b3595068778dd592e39a122f4f5a5cf09c90fe2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Arg [0] (address) : 0xc0aee478e3658e2610c5f7a4a2e1777ce9e4f2ac
Arg [1] (address) : 0x8798249c2e607446efb7ad49ec89dd1865ff4272
Arg [2] (address) : 0x6b3595068778dd592e39a122f4f5a5cf09c90fe2
Arg [3] (address) : 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
contracts/SushiMaker.sol
// SPDX-License-Identifier: MIT
// P1 - P3: OK
pragma solidity 0.6.12;
import "./libraries/BoringMath.sol";
import "./libraries/BoringERC20.sol";
import "./uniswapv2/interfaces/IUniswapV2ERC20.sol";
import "./uniswapv2/interfaces/IUniswapV2Pair.sol";
import "./uniswapv2/interfaces/IUniswapV2Factory.sol";
import "./BoringOwnable.sol";
// SushiMaker is MasterChef's left hand and kinda a wizard. He can cook up Sushi from pretty much anything!
// This contract handles "serving up" rewards for xSushi holders by trading tokens collected from fees for Sushi.
// T1 - T4: OK
contract SushiMaker is BoringOwnable {
using BoringMath for uint256;
using BoringERC20 for IERC20;
// V1 - V5: OK
IUniswapV2Factory public immutable factory;
//0xC0AEe478e3658e2610c5F7A4A2E1777cE9e4f2Ac
// V1 - V5: OK
address public immutable bar;
//0x8798249c2E607446EfB7Ad49eC89dD1865Ff4272
// V1 - V5: OK
address private immutable sushi;
//0x6B3595068778DD592e39A122f4f5a5cF09C90fE2
// V1 - V5: OK
address private immutable weth;
//0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
// V1 - V5: OK
mapping(address => address) internal _bridges;
// E1: OK
event LogBridgeSet(address indexed token, address indexed bridge);
// E1: OK
event LogConvert(address indexed server, address indexed token0, address indexed token1, uint256 amount0, uint256 amount1, uint256 amountSUSHI);
constructor (address _factory, address _bar, address _sushi, address _weth) public {
factory = IUniswapV2Factory(_factory);
bar = _bar;
sushi = _sushi;
weth = _weth;
}
// F1 - F10: OK
// C1 - C24: OK
function bridgeFor(address token) public view returns (address bridge) {
bridge = _bridges[token];
if (bridge == address(0)) {
bridge = weth;
}
}
// F1 - F10: OK
// C1 - C24: OK
function setBridge(address token, address bridge) external onlyOwner {
// Checks
require(token != sushi && token != weth && token != bridge, "SushiMaker: Invalid bridge");
// Effects
_bridges[token] = bridge;
emit LogBridgeSet(token, bridge);
}
// M1 - M5: OK
// C1 - C24: OK
// C6: It's not a fool proof solution, but it prevents flash loans, so here it's ok to use tx.origin
modifier onlyEOA() {
// Try to make flash-loan exploit harder to do.
require(msg.sender == tx.origin, "SushiMaker: must use EOA");
_;
}
// F1 - F10: OK
// F3: _convert is separate to save gas by only checking the 'onlyEOA' modifier once in case of convertMultiple
// F6: There is an exploit to add lots of SUSHI to the bar, run convert, then remove the SUSHI again.
// As the size of the SushiBar has grown, this requires large amounts of funds and isn't super profitable anymore
// The onlyEOA modifier prevents this being done with a flash loan.
// C1 - C24: OK
function convert(address token0, address token1) external onlyEOA() {
_convert(token0, token1);
}
// F1 - F10: OK, see convert
// C1 - C24: OK
// C3: Loop is under control of the caller
function convertMultiple(address[] calldata token0, address[] calldata token1) external onlyEOA() {
// TODO: This can be optimized a fair bit, but this is safer and simpler for now
uint256 len = token0.length;
for(uint256 i=0; i < len; i++) {
_convert(token0[i], token1[i]);
}
}
// F1 - F10: OK
// C1- C24: OK
function _convert(address token0, address token1) internal {
// Interactions
// S1 - S4: OK
IUniswapV2Pair pair = IUniswapV2Pair(factory.getPair(token0, token1));
require(address(pair) != address(0), "SushiMaker: Invalid pair");
// balanceOf: S1 - S4: OK
// transfer: X1 - X5: OK
IERC20(address(pair)).safeTransfer(address(pair), pair.balanceOf(address(this)));
// X1 - X5: OK
(uint256 amount0, uint256 amount1) = pair.burn(address(this));
if (token0 != pair.token0()) {
(amount0, amount1) = (amount1, amount0);
}
emit LogConvert(msg.sender, token0, token1, amount0, amount1, _convertStep(token0, token1, amount0, amount1));
}
// F1 - F10: OK
// C1 - C24: OK
// All safeTransfer, _swap, _toSUSHI, _convertStep: X1 - X5: OK
function _convertStep(address token0, address token1, uint256 amount0, uint256 amount1) internal returns(uint256 sushiOut) {
// Interactions
if (token0 == token1) {
uint256 amount = amount0.add(amount1);
if (token0 == sushi) {
IERC20(sushi).safeTransfer(bar, amount);
sushiOut = amount;
} else if (token0 == weth) {
sushiOut = _toSUSHI(weth, amount);
} else {
address bridge = bridgeFor(token0);
amount = _swap(token0, bridge, amount, address(this));
sushiOut = _convertStep(bridge, bridge, amount, 0);
}
} else if (token0 == sushi) { // eg. SUSHI - ETH
IERC20(sushi).safeTransfer(bar, amount0);
sushiOut = _toSUSHI(token1, amount1).add(amount0);
} else if (token1 == sushi) { // eg. USDT - SUSHI
IERC20(sushi).safeTransfer(bar, amount1);
sushiOut = _toSUSHI(token0, amount0).add(amount1);
} else if (token0 == weth) { // eg. ETH - USDC
sushiOut = _toSUSHI(weth, _swap(token1, weth, amount1, address(this)).add(amount0));
} else if (token1 == weth) { // eg. USDT - ETH
sushiOut = _toSUSHI(weth, _swap(token0, weth, amount0, address(this)).add(amount1));
} else { // eg. MIC - USDT
address bridge0 = bridgeFor(token0);
address bridge1 = bridgeFor(token1);
if (bridge0 == token1) { // eg. MIC - USDT - and bridgeFor(MIC) = USDT
sushiOut = _convertStep(bridge0, token1,
_swap(token0, bridge0, amount0, address(this)),
amount1
);
} else if (bridge1 == token0) { // eg. WBTC - DSD - and bridgeFor(DSD) = WBTC
sushiOut = _convertStep(token0, bridge1,
amount0,
_swap(token1, bridge1, amount1, address(this))
);
} else {
sushiOut = _convertStep(bridge0, bridge1, // eg. USDT - DSD - and bridgeFor(DSD) = WBTC
_swap(token0, bridge0, amount0, address(this)),
_swap(token1, bridge1, amount1, address(this))
);
}
}
}
// F1 - F10: OK
// C1 - C24: OK
// All safeTransfer, swap: X1 - X5: OK
function _swap(address fromToken, address toToken, uint256 amountIn, address to) internal returns (uint256 amountOut) {
// Checks
// X1 - X5: OK
IUniswapV2Pair pair = IUniswapV2Pair(factory.getPair(fromToken, toToken));
require(address(pair) != address(0), "SushiMaker: Cannot convert");
// Interactions
// X1 - X5: OK
(uint256 reserve0, uint256 reserve1,) = pair.getReserves();
uint256 amountInWithFee = amountIn.mul(997);
if (fromToken == pair.token0()) {
amountOut = amountIn.mul(997).mul(reserve1) / reserve0.mul(1000).add(amountInWithFee);
IERC20(fromToken).safeTransfer(address(pair), amountIn);
pair.swap(0, amountOut, to, new bytes(0));
// TODO: Add maximum slippage?
} else {
amountOut = amountIn.mul(997).mul(reserve0) / reserve1.mul(1000).add(amountInWithFee);
IERC20(fromToken).safeTransfer(address(pair), amountIn);
pair.swap(amountOut, 0, to, new bytes(0));
// TODO: Add maximum slippage?
}
}
// F1 - F10: OK
// C1 - C24: OK
function _toSUSHI(address token, uint256 amountIn) internal returns(uint256 amountOut) {
// X1 - X5: OK
amountOut = _swap(token, sushi, amountIn, bar);
}
}
/IERC20.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
// EIP 2612
function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;
}
/IUniswapV2Factory.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.5.0;
interface IUniswapV2Factory {
event PairCreated(address indexed token0, address indexed token1, address pair, uint);
function feeTo() external view returns (address);
function feeToSetter() external view returns (address);
function migrator() external view returns (address);
function getPair(address tokenA, address tokenB) external view returns (address pair);
function allPairs(uint) external view returns (address pair);
function allPairsLength() external view returns (uint);
function createPair(address tokenA, address tokenB) external returns (address pair);
function setFeeTo(address) external;
function setFeeToSetter(address) external;
function setMigrator(address) external;
}
/IUniswapV2ERC20.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.5.0;
interface IUniswapV2ERC20 {
event Approval(address indexed owner, address indexed spender, uint value);
event Transfer(address indexed from, address indexed to, uint value);
function name() external pure returns (string memory);
function symbol() external pure returns (string memory);
function decimals() external pure returns (uint8);
function totalSupply() external view returns (uint);
function balanceOf(address owner) external view returns (uint);
function allowance(address owner, address spender) external view returns (uint);
function approve(address spender, uint value) external returns (bool);
function transfer(address to, uint value) external returns (bool);
function transferFrom(address from, address to, uint value) external returns (bool);
function DOMAIN_SEPARATOR() external view returns (bytes32);
function PERMIT_TYPEHASH() external pure returns (bytes32);
function nonces(address owner) external view returns (uint);
function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;
}
/IUniswapV2Pair.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.5.0;
interface IUniswapV2Pair {
event Approval(address indexed owner, address indexed spender, uint value);
event Transfer(address indexed from, address indexed to, uint value);
function name() external pure returns (string memory);
function symbol() external pure returns (string memory);
function decimals() external pure returns (uint8);
function totalSupply() external view returns (uint);
function balanceOf(address owner) external view returns (uint);
function allowance(address owner, address spender) external view returns (uint);
function approve(address spender, uint value) external returns (bool);
function transfer(address to, uint value) external returns (bool);
function transferFrom(address from, address to, uint value) external returns (bool);
function DOMAIN_SEPARATOR() external view returns (bytes32);
function PERMIT_TYPEHASH() external pure returns (bytes32);
function nonces(address owner) external view returns (uint);
function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;
event Mint(address indexed sender, uint amount0, uint amount1);
event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
event Swap(
address indexed sender,
uint amount0In,
uint amount1In,
uint amount0Out,
uint amount1Out,
address indexed to
);
event Sync(uint112 reserve0, uint112 reserve1);
function MINIMUM_LIQUIDITY() external pure returns (uint);
function factory() external view returns (address);
function token0() external view returns (address);
function token1() external view returns (address);
function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
function price0CumulativeLast() external view returns (uint);
function price1CumulativeLast() external view returns (uint);
function kLast() external view returns (uint);
function mint(address to) external returns (uint liquidity);
function burn(address to) external returns (uint amount0, uint amount1);
function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
function skim(address to) external;
function sync() external;
function initialize(address, address) external;
}
/BoringERC20.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
import "../interfaces/IERC20.sol";
library BoringERC20 {
function safeSymbol(IERC20 token) internal view returns(string memory) {
(bool success, bytes memory data) = address(token).staticcall(abi.encodeWithSelector(0x95d89b41));
return success && data.length > 0 ? abi.decode(data, (string)) : "???";
}
function safeName(IERC20 token) internal view returns(string memory) {
(bool success, bytes memory data) = address(token).staticcall(abi.encodeWithSelector(0x06fdde03));
return success && data.length > 0 ? abi.decode(data, (string)) : "???";
}
function safeDecimals(IERC20 token) public view returns (uint8) {
(bool success, bytes memory data) = address(token).staticcall(abi.encodeWithSelector(0x313ce567));
return success && data.length == 32 ? abi.decode(data, (uint8)) : 18;
}
function safeTransfer(IERC20 token, address to, uint256 amount) internal {
(bool success, bytes memory data) = address(token).call(abi.encodeWithSelector(0xa9059cbb, to, amount));
require(success && (data.length == 0 || abi.decode(data, (bool))), "BentoBox: Transfer failed");
}
function safeTransferFrom(IERC20 token, address from, uint256 amount) internal {
(bool success, bytes memory data) = address(token).call(abi.encodeWithSelector(0x23b872dd, from, address(this), amount));
require(success && (data.length == 0 || abi.decode(data, (bool))), "BentoBox: TransferFrom failed");
}
}
/BoringMath.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
// a library for performing overflow-safe math, updated with awesomeness from of DappHub (https://github.com/dapphub/ds-math)
library BoringMath {
function add(uint256 a, uint256 b) internal pure returns (uint256 c) {require((c = a + b) >= b, "BoringMath: Add Overflow");}
function sub(uint256 a, uint256 b) internal pure returns (uint256 c) {require((c = a - b) <= a, "BoringMath: Underflow");}
function mul(uint256 a, uint256 b) internal pure returns (uint256 c) {require(b == 0 || (c = a * b)/b == a, "BoringMath: Mul Overflow");}
function to128(uint256 a) internal pure returns (uint128 c) {
require(a <= uint128(-1), "BoringMath: uint128 Overflow");
c = uint128(a);
}
}
library BoringMath128 {
function add(uint128 a, uint128 b) internal pure returns (uint128 c) {require((c = a + b) >= b, "BoringMath: Add Overflow");}
function sub(uint128 a, uint128 b) internal pure returns (uint128 c) {require((c = a - b) <= a, "BoringMath: Underflow");}
}
/BoringOwnable.sol
// SPDX-License-Identifier: MIT
// Audit on 5-Jan-2021 by Keno and BoringCrypto
// P1 - P3: OK
pragma solidity 0.6.12;
// Source: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol + Claimable.sol
// Edited by BoringCrypto
// T1 - T4: OK
contract BoringOwnableData {
// V1 - V5: OK
address public owner;
// V1 - V5: OK
address public pendingOwner;
}
// T1 - T4: OK
contract BoringOwnable is BoringOwnableData {
// E1: OK
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor () internal {
owner = msg.sender;
emit OwnershipTransferred(address(0), msg.sender);
}
// F1 - F9: OK
// C1 - C21: OK
function transferOwnership(address newOwner, bool direct, bool renounce) public onlyOwner {
if (direct) {
// Checks
require(newOwner != address(0) || renounce, "Ownable: zero address");
// Effects
emit OwnershipTransferred(owner, newOwner);
owner = newOwner;
} else {
// Effects
pendingOwner = newOwner;
}
}
// F1 - F9: OK
// C1 - C21: OK
function claimOwnership() public {
address _pendingOwner = pendingOwner;
// Checks
require(msg.sender == _pendingOwner, "Ownable: caller != pending owner");
// Effects
emit OwnershipTransferred(owner, _pendingOwner);
owner = _pendingOwner;
pendingOwner = address(0);
}
// M1 - M5: OK
// C1 - C21: OK
modifier onlyOwner() {
require(msg.sender == owner, "Ownable: caller is not the owner");
_;
}
}
Compiler Settings
{"remappings":[],"optimizer":{"runs":5000,"enabled":true},"metadata":{"useLiteralContent":true,"bytecodeHash":"ipfs"},"libraries":{},"evmVersion":"istanbul","compilationTarget":{"contracts/SushiMaker.sol":"SushiMaker"}}
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_factory","internalType":"address"},{"type":"address","name":"_bar","internalType":"address"},{"type":"address","name":"_sushi","internalType":"address"},{"type":"address","name":"_weth","internalType":"address"}]},{"type":"event","name":"LogBridgeSet","inputs":[{"type":"address","name":"token","internalType":"address","indexed":true},{"type":"address","name":"bridge","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"LogConvert","inputs":[{"type":"address","name":"server","internalType":"address","indexed":true},{"type":"address","name":"token0","internalType":"address","indexed":true},{"type":"address","name":"token1","internalType":"address","indexed":true},{"type":"uint256","name":"amount0","internalType":"uint256","indexed":false},{"type":"uint256","name":"amount1","internalType":"uint256","indexed":false},{"type":"uint256","name":"amountSUSHI","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"bar","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"bridge","internalType":"address"}],"name":"bridgeFor","inputs":[{"type":"address","name":"token","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"claimOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"convert","inputs":[{"type":"address","name":"token0","internalType":"address"},{"type":"address","name":"token1","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"convertMultiple","inputs":[{"type":"address[]","name":"token0","internalType":"address[]"},{"type":"address[]","name":"token1","internalType":"address[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IUniswapV2Factory"}],"name":"factory","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"pendingOwner","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setBridge","inputs":[{"type":"address","name":"token","internalType":"address"},{"type":"address","name":"bridge","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"},{"type":"bool","name":"direct","internalType":"bool"},{"type":"bool","name":"renounce","internalType":"bool"}]}]
Contract Creation Code
0x61010060405234801561001157600080fd5b506040516118e93803806118e98339818101604052608081101561003457600080fd5b5080516020820151604080840151606090940151600080546001600160a01b0319163390811782559251949593949192917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a36001600160601b0319606094851b811660805292841b831660a05290831b821660c05290911b1660e05260805160601c60a05160601c60c05160601c60e05160601c6117866101636000398061062e52806107645280610dd15280610e0e5280610fb35280610ff052806110195280611046528061108352806110ac5250806105f15280610d3b5280610d805280610e6e5280610eb35280610f175280610f5c52806111e65250806108205280610da25280610ed55280610f7e52806112085250806107ed5280610846528061123852506117866000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c8063a761a93911610076578063c45a01551161005b578063c45a01551461026b578063e30c397814610273578063febb0f7e1461027b576100be565b8063a761a93914610217578063bd1b820c1461023d576100be565b80634e71e0c8116100a75780634e71e0c8146101bd5780638da5cb5b146101c55780639d22ae8c146101e9576100be565b8063078dfbe7146100c3578063303e6aa4146100fb575b600080fd5b6100f9600480360360608110156100d957600080fd5b506001600160a01b03813516906020810135151590604001351515610283565b005b6100f96004803603604081101561011157600080fd5b81019060208101813564010000000081111561012c57600080fd5b82018360208201111561013e57600080fd5b8035906020019184602083028401116401000000008311171561016057600080fd5b91939092909160208101903564010000000081111561017e57600080fd5b82018360208201111561019057600080fd5b803590602001918460208302840111640100000000831117156101b257600080fd5b5090925090506103f7565b6100f96104a7565b6101cd610581565b604080516001600160a01b039092168252519081900360200190f35b6100f9600480360360408110156101ff57600080fd5b506001600160a01b0381358116916020013516610590565b6101cd6004803603602081101561022d57600080fd5b50356001600160a01b0316610741565b6100f96004803603604081101561025357600080fd5b506001600160a01b0381358116916020013516610789565b6101cd6107eb565b6101cd61080f565b6101cd61081e565b6000546001600160a01b031633146102e2576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b81156103be576001600160a01b0383161515806102fc5750805b61034d576040805162461bcd60e51b815260206004820152601560248201527f4f776e61626c653a207a65726f20616464726573730000000000000000000000604482015290519081900360640190fd5b600080546040516001600160a01b03808716939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0385161790556103f2565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0385161790555b505050565b33321461044b576040805162461bcd60e51b815260206004820152601860248201527f53757368694d616b65723a206d7573742075736520454f410000000000000000604482015290519081900360640190fd5b8260005b8181101561049f5761049786868381811061046657fe5b905060200201356001600160a01b031685858481811061048257fe5b905060200201356001600160a01b0316610842565b60010161044f565b505050505050565b6001546001600160a01b0316338114610507576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c657220213d2070656e64696e67206f776e6572604482015290519081900360640190fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b039092167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179055600180549091169055565b6000546001600160a01b031681565b6000546001600160a01b031633146105ef576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161415801561066357507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614155b80156106815750806001600160a01b0316826001600160a01b031614155b6106d2576040805162461bcd60e51b815260206004820152601a60248201527f53757368694d616b65723a20496e76616c696420627269646765000000000000604482015290519081900360640190fd5b6001600160a01b0382811660008181526002602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169486169485179055517f2e103aa707acc565f9a1547341914802b2bfe977fd79c595209f248ae4b006139190a35050565b6001600160a01b03808216600090815260026020526040902054168061078457507f00000000000000000000000000000000000000000000000000000000000000005b919050565b3332146107dd576040805162461bcd60e51b815260206004820152601860248201527f53757368694d616b65723a206d7573742075736520454f410000000000000000604482015290519081900360640190fd5b6107e78282610842565b5050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6001546001600160a01b031681565b7f000000000000000000000000000000000000000000000000000000000000000081565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e6a4390584846040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b1580156108c257600080fd5b505afa1580156108d6573d6000803e3d6000fd5b505050506040513d60208110156108ec57600080fd5b505190506001600160a01b03811661094b576040805162461bcd60e51b815260206004820152601860248201527f53757368694d616b65723a20496e76616c696420706169720000000000000000604482015290519081900360640190fd5b6109d981826001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561099c57600080fd5b505afa1580156109b0573d6000803e3d6000fd5b505050506040513d60208110156109c657600080fd5b50516001600160a01b0384169190610b59565b600080826001600160a01b03166389afcb44306040518263ffffffff1660e01b815260040180826001600160a01b031681526020019150506040805180830381600087803b158015610a2a57600080fd5b505af1158015610a3e573d6000803e3d6000fd5b505050506040513d6040811015610a5457600080fd5b508051602091820151604080517f0dfe168100000000000000000000000000000000000000000000000000000000815290519295509093506001600160a01b03861692630dfe168192600480840193829003018186803b158015610ab757600080fd5b505afa158015610acb573d6000803e3d6000fd5b505050506040513d6020811015610ae157600080fd5b50516001600160a01b03868116911614610af757905b6001600160a01b03808516908616337fd06b1d7ed79b664d17472c6f6997b929f1abe463ccccb4e5b6a0038f2f730c158585610b358b8b8484610d0f565b60408051938452602084019290925282820152519081900360600190a45050505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000178152925182516000946060949389169392918291908083835b60208310610c2257805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610be5565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610c84576040519150601f19603f3d011682016040523d82523d6000602084013e610c89565b606091505b5091509150818015610cb7575080511580610cb75750808060200190516020811015610cb457600080fd5b50515b610d08576040805162461bcd60e51b815260206004820152601960248201527f42656e746f426f783a205472616e73666572206661696c656400000000000000604482015290519081900360640190fd5b5050505050565b6000836001600160a01b0316856001600160a01b03161415610e6c576000610d378484611180565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316866001600160a01b03161415610dcf57610dc76001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000167f000000000000000000000000000000000000000000000000000000000000000083610b59565b809150610e66565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316866001600160a01b03161415610e3a57610e337f0000000000000000000000000000000000000000000000000000000000000000826111de565b9150610e66565b6000610e4587610741565b9050610e5387828430611233565b9150610e628182846000610d0f565b9250505b50611178565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316856001600160a01b03161415610f1557610efa6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000167f000000000000000000000000000000000000000000000000000000000000000085610b59565b610f0e83610f0886856111de565b90611180565b9050611178565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316846001600160a01b03161415610fb157610fa36001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000167f000000000000000000000000000000000000000000000000000000000000000084610b59565b610f0e82610f0887866111de565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316856001600160a01b0316141561104457610f0e7f000000000000000000000000000000000000000000000000000000000000000061103f85610f08887f00000000000000000000000000000000000000000000000000000000000000008830611233565b6111de565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316846001600160a01b031614156110d257610f0e7f000000000000000000000000000000000000000000000000000000000000000061103f84610f08897f00000000000000000000000000000000000000000000000000000000000000008930611233565b60006110dd86610741565b905060006110ea86610741565b9050856001600160a01b0316826001600160a01b031614156111245761111d82876111178a868a30611233565b87610d0f565b9250611175565b866001600160a01b0316816001600160a01b031614156111555761111d8782876111508a868a30611233565b610d0f565b61117282826111668a868a30611233565b6111508a868a30611233565b92505b50505b949350505050565b818101818110156111d8576040805162461bcd60e51b815260206004820152601860248201527f426f72696e674d6174683a20416464204f766572666c6f770000000000000000604482015290519081900360640190fd5b92915050565b600061122c837f0000000000000000000000000000000000000000000000000000000000000000847f0000000000000000000000000000000000000000000000000000000000000000611233565b9392505050565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e6a4390587876040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b1580156112b457600080fd5b505afa1580156112c8573d6000803e3d6000fd5b505050506040513d60208110156112de57600080fd5b505190506001600160a01b03811661133d576040805162461bcd60e51b815260206004820152601a60248201527f53757368694d616b65723a2043616e6e6f7420636f6e76657274000000000000604482015290519081900360640190fd5b600080826001600160a01b0316630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b15801561137957600080fd5b505afa15801561138d573d6000803e3d6000fd5b505050506040513d60608110156113a357600080fd5b5080516020909101516dffffffffffffffffffffffffffff918216935016905060006113d1876103e56116e4565b9050836001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b15801561140c57600080fd5b505afa158015611420573d6000803e3d6000fd5b505050506040513d602081101561143657600080fd5b50516001600160a01b038a8116911614156115965761145b81610f08856103e86116e4565b6114718361146b8a6103e56116e4565b906116e4565b8161147857fe5b04945061148f6001600160a01b038a168589610b59565b60408051600080825260208201928390527f022c0d9f00000000000000000000000000000000000000000000000000000000835260248201818152604483018990526001600160a01b038a81166064850152608060848501908152845160a48601819052918a169563022c0d9f958c948e9491939092909160c4850191908083838b5b8381101561152a578181015183820152602001611512565b50505050905090810190601f1680156115575780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b15801561157957600080fd5b505af115801561158d573d6000803e3d6000fd5b505050506116d8565b6115a681610f08846103e86116e4565b6115b68461146b8a6103e56116e4565b816115bd57fe5b0494506115d46001600160a01b038a168589610b59565b60408051600080825260208201928390527f022c0d9f00000000000000000000000000000000000000000000000000000000835260248201888152604483018290526001600160a01b038a81166064850152608060848501908152845160a48601819052918a169563022c0d9f958c95948e9491939092909160c4850191908083838a5b83811015611670578181015183820152602001611658565b50505050905090810190601f16801561169d5780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b1580156116bf57600080fd5b505af11580156116d3573d6000803e3d6000fd5b505050505b50505050949350505050565b60008115806116ff575050808202828282816116fc57fe5b04145b6111d8576040805162461bcd60e51b815260206004820152601860248201527f426f72696e674d6174683a204d756c204f766572666c6f770000000000000000604482015290519081900360640190fdfea26469706673582212208cd8748c734c99848846ca35c6023988b55c535b782106ed097332e08962ba7064736f6c634300060c0033000000000000000000000000c0aee478e3658e2610c5f7a4a2e1777ce9e4f2ac0000000000000000000000008798249c2e607446efb7ad49ec89dd1865ff42720000000000000000000000006b3595068778dd592e39a122f4f5a5cf09c90fe2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106100be5760003560e01c8063a761a93911610076578063c45a01551161005b578063c45a01551461026b578063e30c397814610273578063febb0f7e1461027b576100be565b8063a761a93914610217578063bd1b820c1461023d576100be565b80634e71e0c8116100a75780634e71e0c8146101bd5780638da5cb5b146101c55780639d22ae8c146101e9576100be565b8063078dfbe7146100c3578063303e6aa4146100fb575b600080fd5b6100f9600480360360608110156100d957600080fd5b506001600160a01b03813516906020810135151590604001351515610283565b005b6100f96004803603604081101561011157600080fd5b81019060208101813564010000000081111561012c57600080fd5b82018360208201111561013e57600080fd5b8035906020019184602083028401116401000000008311171561016057600080fd5b91939092909160208101903564010000000081111561017e57600080fd5b82018360208201111561019057600080fd5b803590602001918460208302840111640100000000831117156101b257600080fd5b5090925090506103f7565b6100f96104a7565b6101cd610581565b604080516001600160a01b039092168252519081900360200190f35b6100f9600480360360408110156101ff57600080fd5b506001600160a01b0381358116916020013516610590565b6101cd6004803603602081101561022d57600080fd5b50356001600160a01b0316610741565b6100f96004803603604081101561025357600080fd5b506001600160a01b0381358116916020013516610789565b6101cd6107eb565b6101cd61080f565b6101cd61081e565b6000546001600160a01b031633146102e2576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b81156103be576001600160a01b0383161515806102fc5750805b61034d576040805162461bcd60e51b815260206004820152601560248201527f4f776e61626c653a207a65726f20616464726573730000000000000000000000604482015290519081900360640190fd5b600080546040516001600160a01b03808716939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0385161790556103f2565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0385161790555b505050565b33321461044b576040805162461bcd60e51b815260206004820152601860248201527f53757368694d616b65723a206d7573742075736520454f410000000000000000604482015290519081900360640190fd5b8260005b8181101561049f5761049786868381811061046657fe5b905060200201356001600160a01b031685858481811061048257fe5b905060200201356001600160a01b0316610842565b60010161044f565b505050505050565b6001546001600160a01b0316338114610507576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c657220213d2070656e64696e67206f776e6572604482015290519081900360640190fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b039092167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179055600180549091169055565b6000546001600160a01b031681565b6000546001600160a01b031633146105ef576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b7f0000000000000000000000006b3595068778dd592e39a122f4f5a5cf09c90fe26001600160a01b0316826001600160a01b03161415801561066357507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b0316826001600160a01b031614155b80156106815750806001600160a01b0316826001600160a01b031614155b6106d2576040805162461bcd60e51b815260206004820152601a60248201527f53757368694d616b65723a20496e76616c696420627269646765000000000000604482015290519081900360640190fd5b6001600160a01b0382811660008181526002602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169486169485179055517f2e103aa707acc565f9a1547341914802b2bfe977fd79c595209f248ae4b006139190a35050565b6001600160a01b03808216600090815260026020526040902054168061078457507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc25b919050565b3332146107dd576040805162461bcd60e51b815260206004820152601860248201527f53757368694d616b65723a206d7573742075736520454f410000000000000000604482015290519081900360640190fd5b6107e78282610842565b5050565b7f000000000000000000000000c0aee478e3658e2610c5f7a4a2e1777ce9e4f2ac81565b6001546001600160a01b031681565b7f0000000000000000000000008798249c2e607446efb7ad49ec89dd1865ff427281565b60007f000000000000000000000000c0aee478e3658e2610c5f7a4a2e1777ce9e4f2ac6001600160a01b031663e6a4390584846040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b1580156108c257600080fd5b505afa1580156108d6573d6000803e3d6000fd5b505050506040513d60208110156108ec57600080fd5b505190506001600160a01b03811661094b576040805162461bcd60e51b815260206004820152601860248201527f53757368694d616b65723a20496e76616c696420706169720000000000000000604482015290519081900360640190fd5b6109d981826001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561099c57600080fd5b505afa1580156109b0573d6000803e3d6000fd5b505050506040513d60208110156109c657600080fd5b50516001600160a01b0384169190610b59565b600080826001600160a01b03166389afcb44306040518263ffffffff1660e01b815260040180826001600160a01b031681526020019150506040805180830381600087803b158015610a2a57600080fd5b505af1158015610a3e573d6000803e3d6000fd5b505050506040513d6040811015610a5457600080fd5b508051602091820151604080517f0dfe168100000000000000000000000000000000000000000000000000000000815290519295509093506001600160a01b03861692630dfe168192600480840193829003018186803b158015610ab757600080fd5b505afa158015610acb573d6000803e3d6000fd5b505050506040513d6020811015610ae157600080fd5b50516001600160a01b03868116911614610af757905b6001600160a01b03808516908616337fd06b1d7ed79b664d17472c6f6997b929f1abe463ccccb4e5b6a0038f2f730c158585610b358b8b8484610d0f565b60408051938452602084019290925282820152519081900360600190a45050505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000178152925182516000946060949389169392918291908083835b60208310610c2257805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610be5565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610c84576040519150601f19603f3d011682016040523d82523d6000602084013e610c89565b606091505b5091509150818015610cb7575080511580610cb75750808060200190516020811015610cb457600080fd5b50515b610d08576040805162461bcd60e51b815260206004820152601960248201527f42656e746f426f783a205472616e73666572206661696c656400000000000000604482015290519081900360640190fd5b5050505050565b6000836001600160a01b0316856001600160a01b03161415610e6c576000610d378484611180565b90507f0000000000000000000000006b3595068778dd592e39a122f4f5a5cf09c90fe26001600160a01b0316866001600160a01b03161415610dcf57610dc76001600160a01b037f0000000000000000000000006b3595068778dd592e39a122f4f5a5cf09c90fe2167f0000000000000000000000008798249c2e607446efb7ad49ec89dd1865ff427283610b59565b809150610e66565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b0316866001600160a01b03161415610e3a57610e337f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2826111de565b9150610e66565b6000610e4587610741565b9050610e5387828430611233565b9150610e628182846000610d0f565b9250505b50611178565b7f0000000000000000000000006b3595068778dd592e39a122f4f5a5cf09c90fe26001600160a01b0316856001600160a01b03161415610f1557610efa6001600160a01b037f0000000000000000000000006b3595068778dd592e39a122f4f5a5cf09c90fe2167f0000000000000000000000008798249c2e607446efb7ad49ec89dd1865ff427285610b59565b610f0e83610f0886856111de565b90611180565b9050611178565b7f0000000000000000000000006b3595068778dd592e39a122f4f5a5cf09c90fe26001600160a01b0316846001600160a01b03161415610fb157610fa36001600160a01b037f0000000000000000000000006b3595068778dd592e39a122f4f5a5cf09c90fe2167f0000000000000000000000008798249c2e607446efb7ad49ec89dd1865ff427284610b59565b610f0e82610f0887866111de565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b0316856001600160a01b0316141561104457610f0e7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc261103f85610f08887f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28830611233565b6111de565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b0316846001600160a01b031614156110d257610f0e7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc261103f84610f08897f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28930611233565b60006110dd86610741565b905060006110ea86610741565b9050856001600160a01b0316826001600160a01b031614156111245761111d82876111178a868a30611233565b87610d0f565b9250611175565b866001600160a01b0316816001600160a01b031614156111555761111d8782876111508a868a30611233565b610d0f565b61117282826111668a868a30611233565b6111508a868a30611233565b92505b50505b949350505050565b818101818110156111d8576040805162461bcd60e51b815260206004820152601860248201527f426f72696e674d6174683a20416464204f766572666c6f770000000000000000604482015290519081900360640190fd5b92915050565b600061122c837f0000000000000000000000006b3595068778dd592e39a122f4f5a5cf09c90fe2847f0000000000000000000000008798249c2e607446efb7ad49ec89dd1865ff4272611233565b9392505050565b6000807f000000000000000000000000c0aee478e3658e2610c5f7a4a2e1777ce9e4f2ac6001600160a01b031663e6a4390587876040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b1580156112b457600080fd5b505afa1580156112c8573d6000803e3d6000fd5b505050506040513d60208110156112de57600080fd5b505190506001600160a01b03811661133d576040805162461bcd60e51b815260206004820152601a60248201527f53757368694d616b65723a2043616e6e6f7420636f6e76657274000000000000604482015290519081900360640190fd5b600080826001600160a01b0316630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b15801561137957600080fd5b505afa15801561138d573d6000803e3d6000fd5b505050506040513d60608110156113a357600080fd5b5080516020909101516dffffffffffffffffffffffffffff918216935016905060006113d1876103e56116e4565b9050836001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b15801561140c57600080fd5b505afa158015611420573d6000803e3d6000fd5b505050506040513d602081101561143657600080fd5b50516001600160a01b038a8116911614156115965761145b81610f08856103e86116e4565b6114718361146b8a6103e56116e4565b906116e4565b8161147857fe5b04945061148f6001600160a01b038a168589610b59565b60408051600080825260208201928390527f022c0d9f00000000000000000000000000000000000000000000000000000000835260248201818152604483018990526001600160a01b038a81166064850152608060848501908152845160a48601819052918a169563022c0d9f958c948e9491939092909160c4850191908083838b5b8381101561152a578181015183820152602001611512565b50505050905090810190601f1680156115575780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b15801561157957600080fd5b505af115801561158d573d6000803e3d6000fd5b505050506116d8565b6115a681610f08846103e86116e4565b6115b68461146b8a6103e56116e4565b816115bd57fe5b0494506115d46001600160a01b038a168589610b59565b60408051600080825260208201928390527f022c0d9f00000000000000000000000000000000000000000000000000000000835260248201888152604483018290526001600160a01b038a81166064850152608060848501908152845160a48601819052918a169563022c0d9f958c95948e9491939092909160c4850191908083838a5b83811015611670578181015183820152602001611658565b50505050905090810190601f16801561169d5780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b1580156116bf57600080fd5b505af11580156116d3573d6000803e3d6000fd5b505050505b50505050949350505050565b60008115806116ff575050808202828282816116fc57fe5b04145b6111d8576040805162461bcd60e51b815260206004820152601860248201527f426f72696e674d6174683a204d756c204f766572666c6f770000000000000000604482015290519081900360640190fdfea26469706673582212208cd8748c734c99848846ca35c6023988b55c535b782106ed097332e08962ba7064736f6c634300060c0033