Feature Tip: Add private address tag to any address under My Name Tag !
Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| 0x60806040 | 18185025 | 923 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Similar Match Source Code This contract matches the deployed Bytecode of the Source Code for Contract 0x218552ba...4C057D8db The constructor portion of the code might be different and could alter the actual behaviour of the contract
Contract Name:
MBDAAsset
Compiler Version
v0.6.6+commit.6c089d02
Contract Source Code (Solidity)
/**
*Submitted for verification at Etherscan.io on 2020-07-20
*/
pragma solidity ^0.6.4;
pragma experimental ABIEncoderV2;
/**
* SafeMath from OpenZeppelin - commit https://github.com/OpenZeppelin/openzeppelin-contracts/commit/5dfe7215a9156465d550030eadc08770503b2b2f
*
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
* - Subtraction cannot overflow.
*
* _Available since v2.4.0._
*/
function sub(uint256 a, uint256 b, string memory errorMessage)
internal
pure
returns (uint256)
{
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*
* _Available since v2.4.0._
*/
function div(uint256 a, uint256 b, string memory errorMessage)
internal
pure
returns (uint256)
{
// Solidity only automatically asserts when dividing by 0
require(b > 0, errorMessage);
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return mod(a, b, "SafeMath: modulo by zero");
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts with custom message when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*
* _Available since v2.4.0._
*/
function mod(uint256 a, uint256 b, string memory errorMessage)
internal
pure
returns (uint256)
{
require(b != 0, errorMessage);
return a % b;
}
}
/**
* @title MBDAAsset is a template for MB Digital Asset token
* */
contract MBDAAsset {
using SafeMath for uint256;
//
// events
//
// ERC20 events
event Transfer(address indexed _from, address indexed _to, uint256 _value);
event Approval(
address indexed _owner,
address indexed _spender,
uint256 _value
);
// mint/burn events
event Mint(address indexed _to, uint256 _amount, uint256 _newTotalSupply);
event Burn(address indexed _from, uint256 _amount, uint256 _newTotalSupply);
// admin events
event BlockLockSet(uint256 _value);
event NewAdmin(address _newAdmin);
event NewManager(address _newManager);
event NewInvestor(address _newInvestor);
event RemovedInvestor(address _investor);
event FundAssetsChanged(
string indexed tokenSymbol,
string assetInfo,
uint8 amount,
uint256 totalAssetAmount
);
modifier onlyAdmin {
require(msg.sender == admin, "Only admin can perform this operation");
_;
}
modifier managerOrAdmin {
require(
msg.sender == manager || msg.sender == admin,
"Only manager or admin can perform this operation"
);
_;
}
modifier boardOrAdmin {
require(
msg.sender == board || msg.sender == admin,
"Only admin or board can perform this operation"
);
_;
}
modifier blockLock(address _sender) {
require(
!isLocked() || _sender == admin,
"Contract is locked except for the admin"
);
_;
}
modifier onlyIfMintable() {
require(mintable, "Token minting is disabled");
_;
}
struct Asset {
string assetTicker;
string assetInfo;
uint8 assetPercentageParticipation;
}
struct Investor {
string info;
bool exists;
}
uint256 public totalSupply;
string public name;
uint8 public decimals;
string public symbol;
address public admin;
address public board;
address public manager;
uint256 public lockedUntilBlock;
bool public canChangeAssets;
bool public mintable;
bool public hasWhiteList;
bool public isSyndicate;
string public urlFinancialDetailsDocument;
bytes32 public financialDetailsHash;
string[] public tradingPlatforms;
mapping(address => uint256) public balances;
mapping(address => mapping(address => uint256)) public allowed;
mapping(address => Investor) public clearedInvestors;
Asset[] public assets;
/**
* @dev Constructor
* @param _fundAdmin - Fund admin
* @param _fundBoard - Board
* @param _tokenName - Detailed ERC20 token name
* @param _decimalUnits - Detailed ERC20 decimal units
* @param _tokenSymbol - Detailed ERC20 token symbol
* @param _lockedUntilBlock - Block lock
* @param _newTotalSupply - Total Supply owned by the contract itself, only Manager can move
* @param _canChangeAssets - True allows the Manager to change assets in the portfolio
* @param _mintable - True allows Manager to rebalance the portfolio
* @param _hasWhiteList - Allows transfering only between whitelisted addresses
* @param _isSyndicate - Allows secondary market
*/
constructor(
address _fundAdmin,
address _fundBoard,
string memory _tokenName,
uint8 _decimalUnits,
string memory _tokenSymbol,
uint256 _lockedUntilBlock,
uint256 _newTotalSupply,
bool _canChangeAssets,
bool _mintable,
bool _hasWhiteList,
bool _isSyndicate
) public {
name = _tokenName;
require(_decimalUnits <= 18, "Decimal units should be 18 or lower");
decimals = _decimalUnits;
symbol = _tokenSymbol;
lockedUntilBlock = _lockedUntilBlock;
admin = _fundAdmin;
board = _fundBoard;
totalSupply = _newTotalSupply;
canChangeAssets = _canChangeAssets;
mintable = _mintable;
hasWhiteList = _hasWhiteList;
isSyndicate = _isSyndicate;
balances[address(this)] = totalSupply;
Investor memory tmp = Investor("Contract", true);
clearedInvestors[address(this)] = tmp;
emit NewInvestor(address(this));
}
/**
* @dev Set financial details url
* @param _url - URL
* @return True if success
*/
function setFinancialDetails(string memory _url)
public
onlyAdmin
returns (bool)
{
urlFinancialDetailsDocument = _url;
return true;
}
/**
* @dev Set financial details IPFS hash
* @param _hash - URL
* @return True if success
*/
function setFinancialDetailsHash(bytes32 _hash)
public
onlyAdmin
returns (bool)
{
financialDetailsHash = _hash;
return true;
}
/**
* @dev Add trading platform
* @param _details - Details of the trading platform
* @return True if success
*/
function addTradingPlatform(string memory _details)
public
onlyAdmin
returns (bool)
{
tradingPlatforms.push(_details);
return true;
}
/**
* @dev Remove trading platform
* @param _index - Index of the trading platform to be removed
* @return True if success
*/
function removeTradingPlatform(uint256 _index)
public
onlyAdmin
returns (bool)
{
require(_index < tradingPlatforms.length, "Invalid platform index");
tradingPlatforms[_index] = tradingPlatforms[tradingPlatforms.length -
1];
tradingPlatforms.pop();
return true;
}
/**
* @dev Whitelists an Investor
* @param _investor - Address of the investor
* @param _investorInfo - Info
* @return True if success
*/
function addNewInvestor(address _investor, string memory _investorInfo)
public
onlyAdmin
returns (bool)
{
require(_investor != address(0), "Invalid investor address");
Investor memory tmp = Investor(_investorInfo, true);
clearedInvestors[_investor] = tmp;
emit NewInvestor(_investor);
return true;
}
/**
* @dev Removes an Investor from whitelist
* @param _investor - Address of the investor
* @return True if success
*/
function removeInvestor(address _investor) public onlyAdmin returns (bool) {
require(_investor != address(0), "Invalid investor address");
delete (clearedInvestors[_investor]);
emit RemovedInvestor(_investor);
return true;
}
/**
* @dev Add new asset to Portfolio
* @param _assetTicker - Ticker
* @param _assetInfo - Info
* @param _assetPercentageParticipation - % of portfolio taken by the asset
* @return success
*/
function addNewAsset(
string memory _assetTicker,
string memory _assetInfo,
uint8 _assetPercentageParticipation
) public onlyAdmin returns (bool success) {
uint256 totalPercentageAssets = 0;
for (uint256 i = 0; i < assets.length; i++) {
require(
keccak256(bytes(_assetTicker)) !=
keccak256(bytes(assets[i].assetTicker)),
"An asset cannot be assigned twice"
);
totalPercentageAssets = SafeMath.add(
assets[i].assetPercentageParticipation,
totalPercentageAssets
);
}
totalPercentageAssets = SafeMath.add(
totalPercentageAssets,
_assetPercentageParticipation
);
require(
totalPercentageAssets <= 100,
"Total assets number cannot be higher than 100"
);
emit FundAssetsChanged(
_assetTicker,
_assetInfo,
_assetPercentageParticipation,
totalPercentageAssets
);
Asset memory newAsset = Asset(
_assetTicker,
_assetInfo,
_assetPercentageParticipation
);
assets.push(newAsset);
success = true;
return success;
}
/**
* @dev Remove asset from Portfolio
* @param _assetIndex - Asset
* @return True if success
*/
function removeAnAsset(uint8 _assetIndex) public onlyAdmin returns (bool) {
require(canChangeAssets, "Cannot change asset portfolio");
require(
_assetIndex < assets.length,
"Invalid asset index number. Greater than total assets"
);
string memory assetTicker = assets[_assetIndex].assetTicker;
assets[_assetIndex] = assets[assets.length - 1];
delete assets[assets.length - 1];
assets.pop();
emit FundAssetsChanged(assetTicker, "", 0, 0);
return true;
}
/**
* @dev Updates an asset
* @param _assetTicker - Ticker
* @param _assetInfo - Info to update
* @param _newAmount - % of portfolio taken by the asset
* @return True if success
*/
function updateAnAssetQuantity(
string memory _assetTicker,
string memory _assetInfo,
uint8 _newAmount
) public onlyAdmin returns (bool) {
require(canChangeAssets, "Cannot change asset amount");
require(_newAmount > 0, "Cannot set zero asset amount");
uint256 totalAssets = 0;
uint256 assetIndex = 0;
for (uint256 i = 0; i < assets.length; i++) {
if (
keccak256(bytes(_assetTicker)) ==
keccak256(bytes(assets[i].assetTicker))
) {
assetIndex = i;
totalAssets = SafeMath.add(totalAssets, _newAmount);
} else {
totalAssets = SafeMath.add(
totalAssets,
assets[i].assetPercentageParticipation
);
}
}
emit FundAssetsChanged(
_assetTicker,
_assetInfo,
_newAmount,
totalAssets
);
require(
totalAssets <= 100,
"Fund assets total percentage must be less than 100"
);
assets[assetIndex].assetPercentageParticipation = _newAmount;
assets[assetIndex].assetInfo = _assetInfo;
return true;
}
/**
* @return Number of assets in Portfolio
*/
function totalAssetsArray() public view returns (uint256) {
return assets.length;
}
/**
* @dev ERC20 Transfer
* @param _to - destination address
* @param _value - value to transfer
* @return True if success
*/
function transfer(address _to, uint256 _value)
public
blockLock(msg.sender)
returns (bool)
{
address from = (admin == msg.sender) ? address(this) : msg.sender;
require(
isTransferValid(from, _to, _value),
"Invalid Transfer Operation"
);
balances[from] = balances[from].sub(_value);
balances[_to] = balances[_to].add(_value);
emit Transfer(from, _to, _value);
return true;
}
/**
* @dev ERC20 Approve
* @param _spender - destination address
* @param _value - value to be approved
* @return True if success
*/
function approve(address _spender, uint256 _value)
public
blockLock(msg.sender)
returns (bool)
{
require(_spender != address(0), "ERC20: approve to the zero address");
address from = (admin == msg.sender) ? address(this) : msg.sender;
allowed[from][_spender] = _value;
emit Approval(from, _spender, _value);
return true;
}
/**
* @dev ERC20 TransferFrom
* @param _from - source address
* @param _to - destination address
* @param _value - value
* @return True if success
*/
function transferFrom(address _from, address _to, uint256 _value)
public
blockLock(_from)
returns (bool)
{
// check sufficient allowance
require(
_value <= allowed[_from][msg.sender],
"Value informed is invalid"
);
require(
isTransferValid(_from, _to, _value),
"Invalid Transfer Operation"
);
// transfer tokens
balances[_from] = balances[_from].sub(_value);
balances[_to] = balances[_to].add(_value);
allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(
_value,
"Value lower than approval"
);
emit Transfer(_from, _to, _value);
return true;
}
/**
* @dev Mint new tokens. Can only be called by minter or owner
* @param _to - destination address
* @param _value - value
* @return True if success
*/
function mint(address _to, uint256 _value)
public
onlyIfMintable
managerOrAdmin
blockLock(msg.sender)
returns (bool)
{
balances[_to] = balances[_to].add(_value);
totalSupply = totalSupply.add(_value);
emit Mint(_to, _value, totalSupply);
emit Transfer(address(0), _to, _value);
return true;
}
/**
* @dev Burn tokens
* @param _account - address
* @param _value - value
* @return True if success
*/
function burn(address payable _account, uint256 _value)
public
payable
blockLock(msg.sender)
managerOrAdmin
returns (bool)
{
require(_account != address(0), "ERC20: burn from the zero address");
totalSupply = totalSupply.sub(_value);
balances[_account] = balances[_account].sub(_value);
emit Transfer(_account, address(0), _value);
emit Burn(_account, _value, totalSupply);
if (msg.value > 0) {
(bool success, ) = _account.call{value: msg.value}("");
require(success, "Ether transfer failed.");
}
return true;
}
/**
* @dev Set block lock. Until that block (exclusive) transfers are disallowed
* @param _lockedUntilBlock - Block Number
* @return True if success
*/
function setBlockLock(uint256 _lockedUntilBlock)
public
boardOrAdmin
returns (bool)
{
lockedUntilBlock = _lockedUntilBlock;
emit BlockLockSet(_lockedUntilBlock);
return true;
}
/**
* @dev Replace current admin with new one
* @param _newAdmin New token admin
* @return True if success
*/
function replaceAdmin(address _newAdmin)
public
boardOrAdmin
returns (bool)
{
require(_newAdmin != address(0x0), "Null address");
admin = _newAdmin;
emit NewAdmin(_newAdmin);
return true;
}
/**
* @dev Set an account can perform some operations
* @param _newManager Manager address
* @return True if success
*/
function setManager(address _newManager) public onlyAdmin returns (bool) {
manager = _newManager;
emit NewManager(_newManager);
return true;
}
/**
* @dev ERC20 balanceOf
* @param _owner Owner address
* @return True if success
*/
function balanceOf(address _owner) public view returns (uint256) {
return balances[_owner];
}
/**
* @dev ERC20 allowance
* @param _owner Owner address
* @param _spender Address allowed to spend from Owner's balance
* @return uint256 allowance
*/
function allowance(address _owner, address _spender)
public
view
returns (uint256)
{
return allowed[_owner][_spender];
}
/**
* @dev Are transfers currently disallowed
* @return True if disallowed
*/
function isLocked() public view returns (bool) {
return lockedUntilBlock > block.number;
}
/**
* @dev Checks if transfer parameters are valid
* @param _from Source address
* @param _to Destination address
* @param _amount Amount to check
* @return True if valid
*/
function isTransferValid(address _from, address _to, uint256 _amount)
public
view
returns (bool)
{
if (_from == address(0)) {
return false;
}
if (_to == address(0)) {
return false;
}
if (!hasWhiteList) {
return balances[_from] >= _amount; // sufficient balance
}
bool fromOK = clearedInvestors[_from].exists;
if (!isSyndicate) {
return
balances[_from] >= _amount && // sufficient balance
fromOK; // a seller holder within the whitelist
}
bool toOK = clearedInvestors[_to].exists;
return
balances[_from] >= _amount && // sufficient balance
fromOK && // a seller holder within the whitelist
toOK; // a buyer holder within the whitelist
}
}
contract MBDAWallet {
mapping(address => bool) public controllers;
address[] public controllerList;
bytes32 public recipientID;
string public recipient;
modifier onlyController() {
require(controllers[msg.sender], "Sender must be a Controller Member");
_;
}
event EtherReceived(address sender, uint256 amount);
/**
* @dev Constructor
* @param _controller - Controller of the new wallet
* @param recipientExternalID - The Recipient ID (managed externally)
*/
constructor(address _controller, string memory recipientExternalID) public {
require(_controller != address(0), "Invalid address of controller 1");
controllers[_controller] = true;
controllerList.push(_controller);
recipientID = keccak256(abi.encodePacked(recipientExternalID));
recipient = recipientExternalID;
}
/**
* @dev Getter for the total number of controllers
* @return Total number of controllers
*/
function getTotalControllers() public view returns (uint256) {
return controllerList.length;
}
/**
* @dev Adds a new Controller
* @param _controller - Controller to be added
* @return True if success
*/
function newController(address _controller)
public
onlyController
returns (bool)
{
require(!controllers[_controller], "Already a controller");
require(_controller != address(0), "Invalid Controller address");
require(
msg.sender != _controller,
"The sender cannot vote to include himself"
);
controllers[_controller] = true;
controllerList.push(_controller);
return true;
}
/**
* @dev Deletes a Controller
* @param _controller - Controller to be deleted
* @return True if success
*/
function deleteController(address _controller)
public
onlyController
returns (bool)
{
require(_controller != address(0), "Invalid Controller address");
require(
controllerList.length > 1,
"Cannot leave the wallet without a controller"
);
delete (controllers[_controller]);
for (uint256 i = 0; i < controllerList.length; i++) {
if (controllerList[i] == _controller) {
controllerList[i] = controllerList[controllerList.length - 1];
delete controllerList[controllerList.length - 1];
controllerList.pop();
return true;
}
}
return false;
}
/**
* @dev Getter for the wallet balance for a given asset
* @param _assetAddress - Asset to check balance
* @return Balance
*/
function getBalance(address _assetAddress) public view returns (uint256) {
MBDAAsset mbda2 = MBDAAsset(_assetAddress);
return mbda2.balanceOf(address(this));
}
/**
* @dev Transfer and ERC20 asset
* @param _assetAddress - Asset
* @param _recipient - Recipient
* @param _amount - Amount to be transferred
* @notice USE NATIVE TOKEN DECIMAL PLACES
* @return True if success
*/
function transfer(
address _assetAddress,
address _recipient,
uint256 _amount
) public onlyController returns (bool) {
require(_recipient != address(0), "Invalid address");
MBDAAsset mbda = MBDAAsset(_assetAddress);
require(
mbda.balanceOf(address(this)) >= _amount,
"Insufficient balance"
);
return mbda.transfer(_recipient, _amount);
}
/**
* @dev Getter for the Recipient
* @return Recipient (string converted)
*/
function getRecipient() public view returns (string memory) {
return recipient;
}
/**
* @dev Getter for the Recipient ID
* @return Recipient (bytes32)
*/
function getRecipientID() external view returns (bytes32) {
return recipientID;
}
/**
* @dev Change the recipient of the wallet
* @param recipientExternalID - Recipient ID
* @return True if success
*/
function changeRecipient(string memory recipientExternalID)
public
onlyController
returns (bool)
{
recipientID = keccak256(abi.encodePacked(recipientExternalID));
recipient = recipientExternalID;
return true;
}
/**
* @dev Receive
* Emits an event on ether received
*/
receive() external payable {
emit EtherReceived(msg.sender, msg.value);
}
/**
* @dev Withdraw Ether from the contract
* @param _beneficiary - Destination
* @param _amount - Amount
* @return True if success
*/
function withdrawEther(address payable _beneficiary, uint256 _amount)
public
onlyController
returns (bool)
{
require(
address(this).balance >= _amount,
"There is not enough balance"
);
(bool success, ) = _beneficiary.call{value: _amount}("");
require(success, "Transfer failed.");
return success;
}
function isController(address _checkAddress) external view returns (bool) {
return controllers[_checkAddress];
}
}
/**
* @dev Wallet Factory
*/
contract MBDAWalletFactory {
struct Wallet {
string recipientID;
address walletAddress;
address controller;
}
Wallet[] public wallets;
mapping(string => Wallet) public walletsIDMap;
event NewWalletCreated(
address walletAddress,
address indexed controller,
string recipientExternalID
);
/**
* @dev Creates a new wallet
* @param _controller - Controller of the new wallet
* @param recipientExternalID - The Recipient ID (managed externally)
* @return true if success
*/
function CreateWallet(
address _controller,
string memory recipientExternalID
) public returns (bool) {
Wallet memory wallet = walletsIDMap[recipientExternalID];
if (wallet.walletAddress != address(0x0)) {
return false;
}
MBDAWallet newWallet = (new MBDAWallet)(
_controller,
recipientExternalID
);
wallet = Wallet(recipientExternalID, address(newWallet), _controller);
wallets.push(wallet);
walletsIDMap[recipientExternalID] = wallet;
emit NewWalletCreated(
address(newWallet),
_controller,
recipientExternalID
);
return true;
}
/**
* @dev Total Wallets ever created
* @return the total wallets ever created
*/
function getTotalWalletsCreated() public view returns (uint256) {
return wallets.length;
}
/**
* @dev Wallet getter
* @param recipientID recipient ID
* @return Wallet (for frontend use)
*/
function getWallet(string calldata recipientID)
external
view
returns (Wallet memory)
{
require(
walletsIDMap[recipientID].walletAddress != address(0x0),
"invalid wallet"
);
return walletsIDMap[recipientID];
}
}
/**
* @title MBDAManager is a contract that generates tokens that represents a investment fund units and manages them
*/
contract MBDAManager {
struct FundTokenContract {
address fundManager;
address fundContractAddress;
string fundTokenSymbol;
bool exists;
}
FundTokenContract[] public contracts;
mapping(address => FundTokenContract) public contractsMap;
event NewFundCreated(
address indexed fundManager,
address indexed tokenAddress,
string indexed tokenSymbol
);
/**
* @dev Creates a new fund token
* @param _fundManager - Manager
* @param _fundChairman - Chairman
* @param _tokenName - Detailed ERC20 token name
* @param _decimalUnits - Detailed ERC20 decimal units
* @param _tokenSymbol - Detailed ERC20 token symbol
* @param _lockedUntilBlock - Block lock
* @param _newTotalSupply - Total Supply owned by the contract itself, only Manager can move
* @param _canChangeAssets - True allows the Manager to change assets in the portfolio
* @param _mintable - True allows Manager to min new tokens
* @param _hasWhiteList - Allows transfering only between whitelisted addresses
* @param _isSyndicate - Allows secondary market
* @return newFundTokenAddress the address of the newly created token
*/
function newFund(
address _fundManager,
address _fundChairman,
string memory _tokenName,
uint8 _decimalUnits,
string memory _tokenSymbol,
uint256 _lockedUntilBlock,
uint256 _newTotalSupply,
bool _canChangeAssets, // ---> Deixar tudo _canChangeAssets
bool _mintable, // ---> Usar aqui _canMintNewTokens
bool _hasWhiteList,
bool _isSyndicate
) public returns (address newFundTokenAddress) {
MBDAAsset ft = new MBDAAsset(
_fundManager,
_fundChairman,
_tokenName,
_decimalUnits,
_tokenSymbol,
_lockedUntilBlock,
_newTotalSupply,
_canChangeAssets,
_mintable,
_hasWhiteList,
_isSyndicate
);
newFundTokenAddress = address(ft);
FundTokenContract memory ftc = FundTokenContract(
_fundManager,
newFundTokenAddress,
_tokenSymbol,
true
);
contracts.push(ftc);
contractsMap[ftc.fundContractAddress] = ftc;
emit NewFundCreated(_fundManager, newFundTokenAddress, _tokenSymbol);
return newFundTokenAddress;
}
/**
* @return Total number of funds created
*/
function totalContractsGenerated() public view returns (uint256) {
return contracts.length;
}
}
/**
* @title MbdaBoard is the smart contract that will control all funds
* */
contract MbdaBoard {
uint256 public minVotes; //minimum number of votes to execute a proposal
mapping(address => bool) public boardMembers; //board members
address[] public boardMembersList; // array with member addresses
/// @dev types of proposal allowed they are Solidity function signatures (bytes4) default ones are added on deploy later more can be added through a proposal
mapping(string => bytes4) public proposalTypes;
uint256 public totalProposals;
/// @notice proposal Struct
struct Proposal {
string proposalType;
address payable destination;
uint256 value;
uint8 votes;
bool executed;
bool exists;
bytes proposal; /// @dev ABI encoded parameters for the function of the proposal type
bool success;
bytes returnData;
mapping(address => bool) voters;
}
mapping(uint256 => Proposal) public proposals;
/// @dev restricts calls to board members
modifier onlyBoardMember() {
require(boardMembers[msg.sender], "Sender must be a Board Member");
_;
}
/// @dev restricts calls to the board itself (these can only be called from a voted proposal)
modifier onlyBoard() {
require(msg.sender == address(this), "Sender must the Board");
_;
}
/// @dev Events
event NewProposal(
uint256 proposalID,
string indexed proposalType,
bytes proposalPayload
);
event Voted(address boardMember, uint256 proposalId);
event ProposalApprovedAndEnforced(
uint256 proposalID,
bytes payload,
bool success,
bytes returnData
);
event Deposit(uint256 value);
/**
* @dev Constructor
* @param _initialMembers - Initial board's members
* @param _minVotes - minimum votes to approve a proposal
* @param _proposalTypes - Proposal types to add upon deployment
* @param _ProposalTypeDescriptions - Description of the proposal types
*/
constructor(
address[] memory _initialMembers,
uint256 _minVotes,
bytes4[] memory _proposalTypes,
string[] memory _ProposalTypeDescriptions
) public {
require(
_initialMembers.length >= _minVotes,
"Member list length must be equal or higher than minVotes"
);
for (uint256 i = 0; i < _initialMembers.length; i++) {
require(
!boardMembers[_initialMembers[i]],
"Duplicate Board Member sent"
);
boardMembersList.push(_initialMembers[i]);
boardMembers[_initialMembers[i]] = true;
}
minVotes = _minVotes;
// setting up default proposalTypes (board management txs)
proposalTypes["addProposalType"] = 0xeaa0dff1;
proposalTypes["removeProposalType"] = 0x746d26b5;
proposalTypes["changeMinVotes"] = 0x9bad192a;
proposalTypes["addBoardMember"] = 0x1eac03ae;
proposalTypes["removeBoardMember"] = 0x39a169f9;
proposalTypes["replaceBoardMember"] = 0xbec44b4f;
// setting up user provided approved proposalTypes
if (_proposalTypes.length > 0) {
require(
_proposalTypes.length == _ProposalTypeDescriptions.length,
"Proposal types and descriptions do not match"
);
for (uint256 i = 0; i < _proposalTypes.length; i++)
proposalTypes[_ProposalTypeDescriptions[i]] = _proposalTypes[i];
}
}
/**
* @dev Adds a proposal and vote on it (onlyMember)
* @notice every proposal is a transaction to be executed by the board transaction type of proposal have to be previously approved (function sig)
* @param _type - proposal type
* @param _data - proposal data (ABI encoded)
* @param _destination - address to send the transaction to
* @param _value - value of the transaction
* @return proposalID The ID of the proposal
*/
function addProposal(
string memory _type,
bytes memory _data,
address payable _destination,
uint256 _value
) public onlyBoardMember returns (uint256 proposalID) {
require(proposalTypes[_type] != bytes4(0x0), "Invalid proposal type");
totalProposals++;
proposalID = totalProposals;
Proposal memory prop = Proposal(
_type,
_destination,
_value,
0,
false,
true,
_data,
false,
bytes("")
);
proposals[proposalID] = prop;
emit NewProposal(proposalID, _type, _data);
// proposer automatically votes
require(vote(proposalID), "Voting on the new proposal failed");
return proposalID;
}
/**
* @dev Vote on a given proposal (onlyMember)
* @param _proposalID - Proposal ID
* @return True if success
*/
function vote(uint256 _proposalID) public onlyBoardMember returns (bool) {
require(proposals[_proposalID].exists, "The proposal is not found");
require(
!proposals[_proposalID].voters[msg.sender],
"This board member has voted already"
);
require(
!proposals[_proposalID].executed,
"This proposal has been approved and enforced"
);
proposals[_proposalID].votes++;
proposals[_proposalID].voters[msg.sender] = true;
emit Voted(msg.sender, _proposalID);
if (proposals[_proposalID].votes >= minVotes)
executeProposal(_proposalID);
return true;
}
/**
* @dev Executes a proposal (internal)
* @param _proposalID - Proposal ID
*/
function executeProposal(uint256 _proposalID) internal {
Proposal memory prop = proposals[_proposalID];
bytes memory payload = abi.encodePacked(
proposalTypes[prop.proposalType],
prop.proposal
);
proposals[_proposalID].executed = true;
(bool success, bytes memory returnData) = prop.destination.call{value: prop.value}(payload);
proposals[_proposalID].success = success;
proposals[_proposalID].returnData = returnData;
emit ProposalApprovedAndEnforced(
_proposalID,
payload,
success,
returnData
);
}
/**
* @dev Adds a proposal type (onlyBoard)
* @param _id - The name of the proposal Type
* @param _signature - 4 byte signature of the function to be called
* @return True if success
*/
function addProposalType(string memory _id, bytes4 _signature)
public
onlyBoard
returns (bool)
{
proposalTypes[_id] = _signature;
return true;
}
/**
* @dev Removes a proposal type (onlyBoard)
* @param _id - The name of the proposal Type
* @return True if success
*/
function removeProposalType(string memory _id)
public
onlyBoard
returns (bool)
{
proposalTypes[_id] = bytes4("");
return true;
}
/**
* @dev Changes the amount of votes needed to approve a proposal (onlyBoard)
* @param _minVotes - New minimum quorum to approve proposals
* @return True if success
*/
function changeMinVotes(uint256 _minVotes) public onlyBoard returns (bool) {
require(_minVotes > 0, "MinVotes cannot be less than 0");
require(
_minVotes <= boardMembersList.length,
"MinVotes lower than number of members"
);
minVotes = _minVotes;
return true;
}
/**
* @dev Adds a board member (onlyBoard)
* @param _newMember - New member to be added
* @return True if success
*/
function addBoardMember(address _newMember)
public
onlyBoard
returns (bool)
{
require(!boardMembers[_newMember], "Duplicate Board Member sent");
boardMembersList.push(_newMember);
boardMembers[_newMember] = true;
if (boardMembersList.length > 1 && minVotes == 0) {
minVotes = 1;
}
return true;
}
/**
* @dev Removes a board member (onlyBoard)
* @param _member - Member to be added
* @return True if success
*/
function removeBoardMember(address _member)
public
onlyBoard
returns (bool)
{
boardMembers[_member] = false;
for (uint256 i = 0; i < boardMembersList.length; i++) {
if (boardMembersList[i] == _member) {
boardMembersList[i] = boardMembersList[boardMembersList.length -
1];
boardMembersList.pop();
}
}
if (boardMembersList.length < minVotes) {
minVotes = boardMembersList.length;
}
return true;
}
/**
* @dev Replaces a board member (onlyBoard)
* @param _oldMember - Old member to be replaced
* @param _newMember - New member to be added
* @return True if success
*/
function replaceBoardMember(address _oldMember, address _newMember)
public
onlyBoard
returns (bool)
{
require(removeBoardMember(_oldMember), "Failed to remove old member");
return addBoardMember(_newMember);
}
/**
* @dev Receive
*/
receive() external payable {
emit Deposit(msg.value);
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_fundAdmin","type":"address"},{"internalType":"address","name":"_fundBoard","type":"address"},{"internalType":"string","name":"_tokenName","type":"string"},{"internalType":"uint8","name":"_decimalUnits","type":"uint8"},{"internalType":"string","name":"_tokenSymbol","type":"string"},{"internalType":"uint256","name":"_lockedUntilBlock","type":"uint256"},{"internalType":"uint256","name":"_newTotalSupply","type":"uint256"},{"internalType":"bool","name":"_canChangeAssets","type":"bool"},{"internalType":"bool","name":"_mintable","type":"bool"},{"internalType":"bool","name":"_hasWhiteList","type":"bool"},{"internalType":"bool","name":"_isSyndicate","type":"bool"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":true,"internalType":"address","name":"_spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"BlockLockSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newTotalSupply","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"tokenSymbol","type":"string"},{"indexed":false,"internalType":"string","name":"assetInfo","type":"string"},{"indexed":false,"internalType":"uint8","name":"amount","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"totalAssetAmount","type":"uint256"}],"name":"FundAssetsChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newTotalSupply","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_newAdmin","type":"address"}],"name":"NewAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_newInvestor","type":"address"}],"name":"NewInvestor","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_newManager","type":"address"}],"name":"NewManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_investor","type":"address"}],"name":"RemovedInvestor","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"string","name":"_assetTicker","type":"string"},{"internalType":"string","name":"_assetInfo","type":"string"},{"internalType":"uint8","name":"_assetPercentageParticipation","type":"uint8"}],"name":"addNewAsset","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_investor","type":"address"},{"internalType":"string","name":"_investorInfo","type":"string"}],"name":"addNewInvestor","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_details","type":"string"}],"name":"addTradingPlatform","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"assets","outputs":[{"internalType":"string","name":"assetTicker","type":"string"},{"internalType":"string","name":"assetInfo","type":"string"},{"internalType":"uint8","name":"assetPercentageParticipation","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"board","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address payable","name":"_account","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"burn","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"canChangeAssets","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"clearedInvestors","outputs":[{"internalType":"string","name":"info","type":"string"},{"internalType":"bool","name":"exists","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"financialDetailsHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hasWhiteList","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isSyndicate","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"isTransferValid","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockedUntilBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"manager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"mint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"_assetIndex","type":"uint8"}],"name":"removeAnAsset","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_investor","type":"address"}],"name":"removeInvestor","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"removeTradingPlatform","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newAdmin","type":"address"}],"name":"replaceAdmin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lockedUntilBlock","type":"uint256"}],"name":"setBlockLock","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_url","type":"string"}],"name":"setFinancialDetails","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_hash","type":"bytes32"}],"name":"setFinancialDetailsHash","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newManager","type":"address"}],"name":"setManager","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAssetsArray","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tradingPlatforms","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_assetTicker","type":"string"},{"internalType":"string","name":"_assetInfo","type":"string"},{"internalType":"uint8","name":"_newAmount","type":"uint8"}],"name":"updateAnAssetQuantity","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"urlFinancialDetailsDocument","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]Contract Creation Code
0x60806040523480156200001157600080fd5b506040516200314638038062003146833981016040819052620000349162000392565b8851620000499060019060208c0190620001ed565b5060128860ff1611156200007a5760405162461bcd60e51b81526004016200007190620004b3565b60405180910390fd5b6002805460ff191660ff8a1617905586516200009e9060039060208a0190620001ed565b506007869055600480546001600160a01b03199081166001600160a01b038e81169190911790925560058054909116918c1691909117905560008581556008805460ff19168615151761ff001916610100861515021762ff0000191662010000851515021763ff0000001916630100000084151502179055308152600c602052604090208590556200012f62000272565b506040805160808101825260088183019081526710dbdb9d1c9858dd60c21b606083015281526001602080830191909152306000908152600e8252929092208151805192938493620001859284920190620001ed565b50602091909101516001909101805460ff19169115159190911790556040517f97d33a7365e760e859a3453f70484ea24a4aeb75478205a52ac35174ead0ccf690620001d39030906200049f565b60405180910390a1505050505050505050505050620004f6565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200023057805160ff191683800117855562000260565b8280016001018555821562000260579182015b828111156200026057825182559160200191906001019062000243565b506200026e9291506200028a565b5090565b60408051808201909152606081526000602082015290565b620002a791905b808211156200026e576000815560010162000291565b90565b80516001600160a01b0381168114620002c257600080fd5b92915050565b80518015158114620002c257600080fd5b600082601f830112620002ea578081fd5b81516001600160401b038082111562000301578283fd5b6040516020601f8401601f191682018101838111838210171562000323578586fd5b806040525081945083825286818588010111156200034057600080fd5b600092505b8383101562000364578583018101518284018201529182019162000345565b83831115620003765760008185840101525b5050505092915050565b805160ff81168114620002c257600080fd5b60008060008060008060008060008060006101608c8e031215620003b4578687fd5b620003c08d8d620002aa565b9a50620003d18d60208e01620002aa565b60408d0151909a506001600160401b03811115620003ed578788fd5b620003fb8e828f01620002d9565b9950506200040d8d60608e0162000380565b60808d01519098506001600160401b0381111562000429578788fd5b620004378e828f01620002d9565b97505060a08c0151955060c08c01519450620004578d60e08e01620002c8565b9350620004698d6101008e01620002c8565b92506200047b8d6101208e01620002c8565b91506200048d8d6101408e01620002c8565b90509295989b509295989b9093969950565b6001600160a01b0391909116815260200190565b60208082526023908201527f446563696d616c20756e6974732073686f756c64206265203138206f72206c6f6040820152623bb2b960e91b606082015260800190565b612c4080620005066000396000f3fe6080604052600436106102465760003560e01c806366d7a11d11610139578063a9059cbb116100b6578063d8162db71161007a578063d8162db714610681578063dce4e6c214610696578063dd62ed3e146106ab578063e159f3d1146106cb578063f851a440146106e0578063fcf05af7146106f557610246565b8063a9059cbb146105d2578063ab730436146105f2578063c4f4face14610612578063cf35bdd014610632578063d0ebdbe71461066157610246565b80637d5a1d15116100fd5780637d5a1d15146105555780637e33957e1461057557806395d89b41146105955780639dc29fac146105aa578063a4e2d634146105bd57610246565b806366d7a11d146104c857806370a08231146104dd57806372379f60146104fd57806377b271a4146105125780637cd3229a1461054057610246565b8063313ce567116101c7578063481c6a751161018b578063481c6a75146104315780634bf365df1461045357806356bd7c8b146104685780635c658165146104885780635fb10858146104a857610246565b8063313ce5671461038f578063366a68dc146103b157806340c10f19146103d157806340ecb7f2146103f1578063427149781461041157610246565b80631dc323c61161020e5780631dc323c6146102fa57806323b872dd1461030f57806327e235e31461032f57806329d8ca2f1461034f5780632dd6be771461036f57610246565b806304b4c2051461024b57806304c3033f1461027657806306fdde03146102a3578063095ea7b3146102c557806318160ddd146102e5575b600080fd5b34801561025757600080fd5b50610260610715565b60405161026d91906125a7565b60405180910390f35b34801561028257600080fd5b50610296610291366004612443565b61071b565b60405161026d919061259c565b3480156102af57600080fd5b506102b861092c565b60405161026d91906125b0565b3480156102d157600080fd5b506102966102e03660046123de565b6109b9565b3480156102f157600080fd5b50610260610aaf565b34801561030657600080fd5b50610296610ab5565b34801561031b57600080fd5b5061029661032a366004612350565b610abe565b34801561033b57600080fd5b5061026061034a3660046122d1565b610c89565b34801561035b57600080fd5b5061029661036a366004612443565b610c9b565b34801561037b57600080fd5b506102b861038a3660046123f0565b610e95565b34801561039b57600080fd5b506103a4610f08565b60405161026d9190612b97565b3480156103bd57600080fd5b506102966103cc3660046123f0565b610f11565b3480156103dd57600080fd5b506102966103ec3660046123de565b610f98565b3480156103fd57600080fd5b5061029661040c366004612350565b611121565b34801561041d57600080fd5b5061029661042c3660046122d1565b611232565b34801561043d57600080fd5b506104466112e4565b60405161026d9190612588565b34801561045f57600080fd5b506102966112f3565b34801561047457600080fd5b506102966104833660046123f0565b611301565b34801561049457600080fd5b506102606104a3366004612318565b611337565b3480156104b457600080fd5b506102966104c3366004612408565b611354565b3480156104d457600080fd5b506102966113cd565b3480156104e957600080fd5b506102606104f83660046122d1565b6113dc565b34801561050957600080fd5b506102966113f7565b34801561051e57600080fd5b5061053261052d3660046122d1565b611407565b60405161026d9291906125c3565b34801561054c57600080fd5b506104466114b1565b34801561056157600080fd5b506102966105703660046123f0565b6114c0565b34801561058157600080fd5b50610296610590366004612408565b611592565b3480156105a157600080fd5b506102b86115d2565b6102966105b83660046122ed565b61162d565b3480156105c957600080fd5b50610296611825565b3480156105de57600080fd5b506102966105ed3660046123de565b61182e565b3480156105fe57600080fd5b5061029661060d3660046124b5565b611952565b34801561061e57600080fd5b5061029661062d3660046122d1565b611c01565b34801561063e57600080fd5b5061065261064d3660046123f0565b611cb4565b60405161026d939291906125e7565b34801561066d57600080fd5b5061029661067c3660046122d1565b611e0b565b34801561068d57600080fd5b50610260611e83565b3480156106a257600080fd5b506102b8611e89565b3480156106b757600080fd5b506102606106c6366004612318565b611ee4565b3480156106d757600080fd5b50610260611f11565b3480156106ec57600080fd5b50610446611f17565b34801561070157600080fd5b50610296610710366004612390565b611f26565b600a5481565b6004546000906001600160a01b031633146107515760405162461bcd60e51b8152600401610748906128a8565b60405180910390fd5b6000805b600f548110156107ef57600f818154811061076c57fe5b906000526020600020906003020160000160405161078a91906124fc565b6040518091039020868051906020012014156107b85760405162461bcd60e51b8152600401610748906127c3565b6107e5600f82815481106107c857fe5b600091825260209091206002600390920201015460ff1683612023565b9150600101610755565b506107fd818460ff16612023565b905060648111156108205760405162461bcd60e51b815260040161074890612678565b8460405161082e919061256c565b60405180910390207fdb5520a9f634155cff8e22a364080e6765f0d52cff4cbac09d4f8864c07d3c9285858460405161086993929190612620565b60405180910390a26108796120b2565b5060408051606081018252868152602080820187905260ff861692820192909252600f8054600181018255600091909152815180519293849360039093027f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac80201926108e792849201906120d6565b50602082810151805161090092600185019201906120d6565b50604091909101516002909101805460ff191660ff9092169190911790555060019150505b9392505050565b60018054604080516020600284861615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156109b15780601f10610986576101008083540402835291602001916109b1565b820191906000526020600020905b81548152906001019060200180831161099457829003601f168201915b505050505081565b6000336109c4611825565b15806109dd57506004546001600160a01b038281169116145b6109f95760405162461bcd60e51b815260040161074890612861565b6001600160a01b038416610a1f5760405162461bcd60e51b81526004016107489061274a565b6004546000906001600160a01b03163314610a3a5733610a3c565b305b6001600160a01b038082166000818152600d60209081526040808320948b1680845294909152908190208890555192935090917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610a9c9088906125a7565b60405180910390a3506001949350505050565b60005481565b60085460ff1681565b600083610ac9611825565b1580610ae257506004546001600160a01b038281169116145b610afe5760405162461bcd60e51b815260040161074890612861565b6001600160a01b0385166000908152600d60209081526040808320338452909152902054831115610b415760405162461bcd60e51b815260040161074890612b52565b610b4c858585611121565b610b685760405162461bcd60e51b8152600401610748906126c5565b6001600160a01b0385166000908152600c6020526040902054610b91908463ffffffff61204816565b6001600160a01b038087166000908152600c60205260408082209390935590861681522054610bc6908463ffffffff61202316565b6001600160a01b038086166000908152600c602090815260408083209490945583518085018552601981527f56616c7565206c6f776572207468616e20617070726f76616c00000000000000818301529289168252600d815283822033835290529190912054610c3d91859063ffffffff61208616565b6001600160a01b038087166000818152600d60209081526040808320338452909152908190209390935591519086169190600080516020612beb83398151915290610a9c9087906125a7565b600c6020526000908152604090205481565b6004546000906001600160a01b03163314610cc85760405162461bcd60e51b8152600401610748906128a8565b60085460ff16610cea5760405162461bcd60e51b81526004016107489061295e565b60008260ff1611610d0d5760405162461bcd60e51b815260040161074890612ae4565b600080805b600f54811015610dac57600f8181548110610d2957fe5b9060005260206000209060030201600001604051610d4791906124fc565b604051809103902087805190602001201415610d7457809150610d6d838660ff16612023565b9250610da4565b610da183600f8381548110610d8557fe5b600091825260209091206002600390920201015460ff16612023565b92505b600101610d12565b5085604051610dbb919061256c565b60405180910390207fdb5520a9f634155cff8e22a364080e6765f0d52cff4cbac09d4f8864c07d3c92868685604051610df693929190612620565b60405180910390a26064821115610e1f5760405162461bcd60e51b815260040161074890612995565b83600f8281548110610e2d57fe5b906000526020600020906003020160020160006101000a81548160ff021916908360ff16021790555084600f8281548110610e6457fe5b90600052602060002090600302016001019080519060200190610e889291906120d6565b5060019695505050505050565b600b8181548110610ea257fe5b600091825260209182902001805460408051601f60026000196101006001871615020190941693909304928301859004850281018501909152818152935090918301828280156109b15780601f10610986576101008083540402835291602001916109b1565b60025460ff1681565b6005546000906001600160a01b0316331480610f3757506004546001600160a01b031633145b610f535760405162461bcd60e51b8152600401610748906126fc565b60078290556040517f6c04066f6ede40cc1642c211ba9d18f1a096ccc84fb8d11be28ea6c3c6f68b3690610f889084906125a7565b60405180910390a1506001919050565b600854600090610100900460ff16610fc25760405162461bcd60e51b815260040161074890612a3c565b6006546001600160a01b0316331480610fe557506004546001600160a01b031633145b6110015760405162461bcd60e51b815260040161074890612a73565b3361100a611825565b158061102357506004546001600160a01b038281169116145b61103f5760405162461bcd60e51b815260040161074890612861565b6001600160a01b0384166000908152600c6020526040902054611068908463ffffffff61202316565b6001600160a01b0385166000908152600c602052604081209190915554611095908463ffffffff61202316565b60008190556040516001600160a01b038616917f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f916110d5918791612b89565b60405180910390a2836001600160a01b031660006001600160a01b0316600080516020612beb8339815191528560405161110f91906125a7565b60405180910390a35060019392505050565b60006001600160a01b03841661113957506000610925565b6001600160a01b03831661114f57506000610925565b60085462010000900460ff1661118157506001600160a01b0383166000908152600c6020526040902054811115610925565b6001600160a01b0384166000908152600e602052604090206001015460085460ff918216916301000000909104166111e0576001600160a01b0385166000908152600c602052604090205483118015906111d85750805b915050610925565b6001600160a01b038085166000908152600e60209081526040808320600101549389168352600c90915290205460ff90911690841180159061121f5750815b80156112285750805b9695505050505050565b6004546000906001600160a01b0316331461125f5760405162461bcd60e51b8152600401610748906128a8565b6001600160a01b0382166112855760405162461bcd60e51b815260040161074890612804565b6001600160a01b0382166000908152600e60205260408120906112a88282612154565b50600101805460ff191690556040517f24ee917fffe923f5cbaf9746ee4c53401b4cf82e794c88724e8a6946b5302ae590610f88908490612588565b6006546001600160a01b031681565b600854610100900460ff1681565b6004546000906001600160a01b0316331461132e5760405162461bcd60e51b8152600401610748906128a8565b50600a55600190565b600d60209081526000928352604080842090915290825290205481565b6004546000906001600160a01b031633146113815760405162461bcd60e51b8152600401610748906128a8565b600b805460018101825560009190915282516113c4917f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db9019060208501906120d6565b50600192915050565b60085462010000900460ff1681565b6001600160a01b03166000908152600c602052604090205490565b6008546301000000900460ff1681565b600e6020908152600091825260409182902080548351601f6002600019610100600186161502019093169290920491820184900484028101840190945280845290929183919083018282801561149e5780601f106114735761010080835404028352916020019161149e565b820191906000526020600020905b81548152906001019060200180831161148157829003601f168201915b5050506001909301549192505060ff1682565b6005546001600160a01b031681565b6004546000906001600160a01b031633146114ed5760405162461bcd60e51b8152600401610748906128a8565b600b54821061150e5760405162461bcd60e51b815260040161074890612648565b600b8054600019810190811061152057fe5b90600052602060002001600b838154811061153757fe5b90600052602060002001908054600181600116156101000203166002900461156092919061219b565b50600b80548061156c57fe5b6001900381819060005260206000200160006115889190612154565b9055506001919050565b6004546000906001600160a01b031633146115bf5760405162461bcd60e51b8152600401610748906128a8565b81516113c49060099060208501906120d6565b6003805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156109b15780601f10610986576101008083540402835291602001916109b1565b600033611638611825565b158061165157506004546001600160a01b038281169116145b61166d5760405162461bcd60e51b815260040161074890612861565b6006546001600160a01b031633148061169057506004546001600160a01b031633145b6116ac5760405162461bcd60e51b815260040161074890612a73565b6001600160a01b0384166116d25760405162461bcd60e51b81526004016107489061291d565b6000546116e5908463ffffffff61204816565b60009081556001600160a01b0385168152600c6020526040902054611710908463ffffffff61204816565b6001600160a01b0385166000818152600c6020526040808220939093559151600080516020612beb8339815191529061174a9087906125a7565b60405180910390a3836001600160a01b03167f49995e5dd6158cf69ad3e9777c46755a1a826a446c6416992167462dad033b2a8460005460405161178f929190612b89565b60405180910390a2341561181b576000846001600160a01b0316346040516117b69061182b565b60006040518083038185875af1925050503d80600081146117f3576040519150601f19603f3d011682016040523d82523d6000602084013e6117f8565b606091505b50509050806118195760405162461bcd60e51b8152600401610748906128ed565b505b5060019392505050565b60075443105b90565b600033611839611825565b158061185257506004546001600160a01b038281169116145b61186e5760405162461bcd60e51b815260040161074890612861565b6004546000906001600160a01b03163314611889573361188b565b305b9050611898818686611121565b6118b45760405162461bcd60e51b8152600401610748906126c5565b6001600160a01b0381166000908152600c60205260409020546118dd908563ffffffff61204816565b6001600160a01b038083166000908152600c60205260408082209390935590871681522054611912908563ffffffff61202316565b6001600160a01b038087166000818152600c60205260409081902093909355915190831690600080516020612beb83398151915290610a9c9088906125a7565b6004546000906001600160a01b0316331461197f5760405162461bcd60e51b8152600401610748906128a8565b60085460ff166119a15760405162461bcd60e51b815260040161074890612b1b565b600f5460ff8316106119c55760405162461bcd60e51b8152600401610748906129e7565b6060600f8360ff16815481106119d757fe5b6000918252602091829020600390910201805460408051601f6002600019610100600187161502019094169390930492830185900485028101850190915281815292830182828015611a6a5780601f10611a3f57610100808354040283529160200191611a6a565b820191906000526020600020905b815481529060010190602001808311611a4d57829003601f168201915b50505050509050600f6001600f805490500381548110611a8657fe5b9060005260206000209060030201600f8460ff1681548110611aa457fe5b906000526020600020906003020160008201816000019080546001816001161561010002031660029004611ad992919061219b565b5060018201816001019080546001816001161561010002031660029004611b0192919061219b565b506002918201549101805460ff191660ff909216919091179055600f80546000198101908110611b2d57fe5b60009182526020822060039091020190611b478282612154565b611b55600183016000612154565b50600201805460ff19169055600f805480611b6c57fe5b60008281526020812060001990920191600383020190611b8c8282612154565b611b9a600183016000612154565b50600201805460ff191690559055604051611bb690829061256c565b60405180910390207fdb5520a9f634155cff8e22a364080e6765f0d52cff4cbac09d4f8864c07d3c92600080604051611bf0929190612ac3565b60405180910390a250600192915050565b6005546000906001600160a01b0316331480611c2757506004546001600160a01b031633145b611c435760405162461bcd60e51b8152600401610748906126fc565b6001600160a01b038216611c695760405162461bcd60e51b81526004016107489061283b565b600480546001600160a01b0319166001600160a01b0384161790556040517f71614071b88dee5e0b2ae578a9dd7b2ebbe9ae832ba419dc0242cd065a290b6c90610f88908490612588565b600f8181548110611cc157fe5b60009182526020918290206003919091020180546040805160026001841615610100026000190190931692909204601f810185900485028301850190915280825291935091839190830182828015611d5a5780601f10611d2f57610100808354040283529160200191611d5a565b820191906000526020600020905b815481529060010190602001808311611d3d57829003601f168201915b505050505090806001018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611df85780601f10611dcd57610100808354040283529160200191611df8565b820191906000526020600020905b815481529060010190602001808311611ddb57829003601f168201915b5050506002909301549192505060ff1683565b6004546000906001600160a01b03163314611e385760405162461bcd60e51b8152600401610748906128a8565b600680546001600160a01b0319166001600160a01b0384161790556040517f5589a1df7a257347b14b97cb6fe06862c960ff64e9a0c2908632929098bb013090610f88908490612588565b60075481565b6009805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156109b15780601f10610986576101008083540402835291602001916109b1565b6001600160a01b038083166000908152600d60209081526040808320938516835292905220545b92915050565b600f5490565b6004546001600160a01b031681565b6004546000906001600160a01b03163314611f535760405162461bcd60e51b8152600401610748906128a8565b6001600160a01b038316611f795760405162461bcd60e51b815260040161074890612804565b611f81612210565b5060408051808201825283815260016020808301919091526001600160a01b0386166000908152600e8252929092208151805192938493611fc592849201906120d6565b50602091909101516001909101805460ff19169115159190911790556040517f97d33a7365e760e859a3453f70484ea24a4aeb75478205a52ac35174ead0ccf690612011908690612588565b60405180910390a15060019392505050565b6000828201838110156109255760405162461bcd60e51b81526004016107489061278c565b600061092583836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152505b600081848411156120aa5760405162461bcd60e51b815260040161074891906125b0565b505050900390565b60405180606001604052806060815260200160608152602001600060ff1681525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061211757805160ff1916838001178555612144565b82800160010185558215612144579182015b82811115612144578251825591602001919060010190612129565b50612150929150612228565b5090565b50805460018160011615610100020316600290046000825580601f1061217a5750612198565b601f0160209004906000526020600020908101906121989190612228565b50565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106121d45780548555612144565b8280016001018555821561214457600052602060002091601f016020900482015b828111156121445782548255916001019190600101906121f5565b60408051808201909152606081526000602082015290565b61182b91905b80821115612150576000815560010161222e565b600082601f830112612252578081fd5b813567ffffffffffffffff80821115612269578283fd5b604051601f8301601f191681016020018281118282101715612289578485fd5b6040528281529250828483016020018610156122a457600080fd5b8260208601602083013760006020848301015250505092915050565b803560ff81168114611f0b57600080fd5b6000602082840312156122e2578081fd5b813561092581612bd5565b600080604083850312156122ff578081fd5b823561230a81612bd5565b946020939093013593505050565b6000806040838503121561232a578182fd5b823561233581612bd5565b9150602083013561234581612bd5565b809150509250929050565b600080600060608486031215612364578081fd5b833561236f81612bd5565b9250602084013561237f81612bd5565b929592945050506040919091013590565b600080604083850312156123a2578182fd5b82356123ad81612bd5565b9150602083013567ffffffffffffffff8111156123c8578182fd5b6123d485828601612242565b9150509250929050565b600080604083850312156122ff578182fd5b600060208284031215612401578081fd5b5035919050565b600060208284031215612419578081fd5b813567ffffffffffffffff81111561242f578182fd5b61243b84828501612242565b949350505050565b600080600060608486031215612457578283fd5b833567ffffffffffffffff8082111561246e578485fd5b61247a87838801612242565b9450602086013591508082111561248f578384fd5b5061249c86828701612242565b9250506124ac85604086016122c0565b90509250925092565b6000602082840312156124c6578081fd5b61092583836122c0565b600081518084526124e8816020860160208601612ba5565b601f01601f19169290920160200192915050565b600080835460018082166000811461251b576001811461253257612561565b60ff198316865260028304607f1686019350612561565b600283048786526020808720875b838110156125595781548a820152908501908201612540565b505050860193505b509195945050505050565b6000825161257e818460208701612ba5565b9190910192915050565b6001600160a01b0391909116815260200190565b901515815260200190565b90815260200190565b60006020825261092560208301846124d0565b6000604082526125d660408301856124d0565b905082151560208301529392505050565b6000606082526125fa60608301866124d0565b828103602084015261260c81866124d0565b91505060ff83166040830152949350505050565b60006060825261263360608301866124d0565b60ff9490941660208301525060400152919050565b602080825260169082015275092dcecc2d8d2c840e0d8c2e8ccdee4da40d2dcc8caf60531b604082015260600190565b6020808252602d908201527f546f74616c20617373657473206e756d6265722063616e6e6f7420626520686960408201526c067686572207468616e2031303609c1b606082015260800190565b6020808252601a908201527f496e76616c6964205472616e73666572204f7065726174696f6e000000000000604082015260600190565b6020808252602e908201527f4f6e6c792061646d696e206f7220626f6172642063616e20706572666f726d2060408201526d3a3434b99037b832b930ba34b7b760911b606082015260800190565b60208082526022908201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604082015261737360f01b606082015260800190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526021908201527f416e2061737365742063616e6e6f742062652061737369676e656420747769636040820152606560f81b606082015260800190565b60208082526018908201527f496e76616c696420696e766573746f7220616464726573730000000000000000604082015260600190565b6020808252600c908201526b4e756c6c206164647265737360a01b604082015260600190565b60208082526027908201527f436f6e7472616374206973206c6f636b65642065786365707420666f72207468604082015266329030b236b4b760c91b606082015260800190565b60208082526025908201527f4f6e6c792061646d696e2063616e20706572666f726d2074686973206f70657260408201526430ba34b7b760d91b606082015260800190565b60208082526016908201527522ba3432b9103a3930b739b332b9103330b4b632b21760511b604082015260600190565b60208082526021908201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736040820152607360f81b606082015260800190565b6020808252601a908201527f43616e6e6f74206368616e676520617373657420616d6f756e74000000000000604082015260600190565b60208082526032908201527f46756e642061737365747320746f74616c2070657263656e74616765206d7573604082015271074206265206c657373207468616e203130360741b606082015260800190565b60208082526035908201527f496e76616c696420617373657420696e646578206e756d6265722e2047726561604082015274746572207468616e20746f74616c2061737365747360581b606082015260800190565b60208082526019908201527f546f6b656e206d696e74696e672069732064697361626c656400000000000000604082015260600190565b60208082526030908201527f4f6e6c79206d616e61676572206f722061646d696e2063616e20706572666f7260408201526f36903a3434b99037b832b930ba34b7b760811b606082015260800190565b606080825260009082015260ff929092166020830152604082015260800190565b6020808252601c908201527f43616e6e6f7420736574207a65726f20617373657420616d6f756e7400000000604082015260600190565b6020808252601d908201527f43616e6e6f74206368616e676520617373657420706f7274666f6c696f000000604082015260600190565b60208082526019908201527f56616c756520696e666f726d656420697320696e76616c696400000000000000604082015260600190565b918252602082015260400190565b60ff91909116815260200190565b60005b83811015612bc0578181015183820152602001612ba8565b83811115612bcf576000848401525b50505050565b6001600160a01b038116811461219857600080fdfeddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa264697066735822122087c4fbd1b419a6e7c40ccbbfa6dfb33151f46f9229cd3848014d1b69cdbde30a64736f6c63430006060033000000000000000000000000a399a95ca71264d5ffdbf5e40349a895cda71ef2000000000000000000000000c07f8246836757fd0f2f7c2570b35cee30eee5c20000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004a817c8000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f417363656e737573202d2046503336000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000075246444650333600000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106102465760003560e01c806366d7a11d11610139578063a9059cbb116100b6578063d8162db71161007a578063d8162db714610681578063dce4e6c214610696578063dd62ed3e146106ab578063e159f3d1146106cb578063f851a440146106e0578063fcf05af7146106f557610246565b8063a9059cbb146105d2578063ab730436146105f2578063c4f4face14610612578063cf35bdd014610632578063d0ebdbe71461066157610246565b80637d5a1d15116100fd5780637d5a1d15146105555780637e33957e1461057557806395d89b41146105955780639dc29fac146105aa578063a4e2d634146105bd57610246565b806366d7a11d146104c857806370a08231146104dd57806372379f60146104fd57806377b271a4146105125780637cd3229a1461054057610246565b8063313ce567116101c7578063481c6a751161018b578063481c6a75146104315780634bf365df1461045357806356bd7c8b146104685780635c658165146104885780635fb10858146104a857610246565b8063313ce5671461038f578063366a68dc146103b157806340c10f19146103d157806340ecb7f2146103f1578063427149781461041157610246565b80631dc323c61161020e5780631dc323c6146102fa57806323b872dd1461030f57806327e235e31461032f57806329d8ca2f1461034f5780632dd6be771461036f57610246565b806304b4c2051461024b57806304c3033f1461027657806306fdde03146102a3578063095ea7b3146102c557806318160ddd146102e5575b600080fd5b34801561025757600080fd5b50610260610715565b60405161026d91906125a7565b60405180910390f35b34801561028257600080fd5b50610296610291366004612443565b61071b565b60405161026d919061259c565b3480156102af57600080fd5b506102b861092c565b60405161026d91906125b0565b3480156102d157600080fd5b506102966102e03660046123de565b6109b9565b3480156102f157600080fd5b50610260610aaf565b34801561030657600080fd5b50610296610ab5565b34801561031b57600080fd5b5061029661032a366004612350565b610abe565b34801561033b57600080fd5b5061026061034a3660046122d1565b610c89565b34801561035b57600080fd5b5061029661036a366004612443565b610c9b565b34801561037b57600080fd5b506102b861038a3660046123f0565b610e95565b34801561039b57600080fd5b506103a4610f08565b60405161026d9190612b97565b3480156103bd57600080fd5b506102966103cc3660046123f0565b610f11565b3480156103dd57600080fd5b506102966103ec3660046123de565b610f98565b3480156103fd57600080fd5b5061029661040c366004612350565b611121565b34801561041d57600080fd5b5061029661042c3660046122d1565b611232565b34801561043d57600080fd5b506104466112e4565b60405161026d9190612588565b34801561045f57600080fd5b506102966112f3565b34801561047457600080fd5b506102966104833660046123f0565b611301565b34801561049457600080fd5b506102606104a3366004612318565b611337565b3480156104b457600080fd5b506102966104c3366004612408565b611354565b3480156104d457600080fd5b506102966113cd565b3480156104e957600080fd5b506102606104f83660046122d1565b6113dc565b34801561050957600080fd5b506102966113f7565b34801561051e57600080fd5b5061053261052d3660046122d1565b611407565b60405161026d9291906125c3565b34801561054c57600080fd5b506104466114b1565b34801561056157600080fd5b506102966105703660046123f0565b6114c0565b34801561058157600080fd5b50610296610590366004612408565b611592565b3480156105a157600080fd5b506102b86115d2565b6102966105b83660046122ed565b61162d565b3480156105c957600080fd5b50610296611825565b3480156105de57600080fd5b506102966105ed3660046123de565b61182e565b3480156105fe57600080fd5b5061029661060d3660046124b5565b611952565b34801561061e57600080fd5b5061029661062d3660046122d1565b611c01565b34801561063e57600080fd5b5061065261064d3660046123f0565b611cb4565b60405161026d939291906125e7565b34801561066d57600080fd5b5061029661067c3660046122d1565b611e0b565b34801561068d57600080fd5b50610260611e83565b3480156106a257600080fd5b506102b8611e89565b3480156106b757600080fd5b506102606106c6366004612318565b611ee4565b3480156106d757600080fd5b50610260611f11565b3480156106ec57600080fd5b50610446611f17565b34801561070157600080fd5b50610296610710366004612390565b611f26565b600a5481565b6004546000906001600160a01b031633146107515760405162461bcd60e51b8152600401610748906128a8565b60405180910390fd5b6000805b600f548110156107ef57600f818154811061076c57fe5b906000526020600020906003020160000160405161078a91906124fc565b6040518091039020868051906020012014156107b85760405162461bcd60e51b8152600401610748906127c3565b6107e5600f82815481106107c857fe5b600091825260209091206002600390920201015460ff1683612023565b9150600101610755565b506107fd818460ff16612023565b905060648111156108205760405162461bcd60e51b815260040161074890612678565b8460405161082e919061256c565b60405180910390207fdb5520a9f634155cff8e22a364080e6765f0d52cff4cbac09d4f8864c07d3c9285858460405161086993929190612620565b60405180910390a26108796120b2565b5060408051606081018252868152602080820187905260ff861692820192909252600f8054600181018255600091909152815180519293849360039093027f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac80201926108e792849201906120d6565b50602082810151805161090092600185019201906120d6565b50604091909101516002909101805460ff191660ff9092169190911790555060019150505b9392505050565b60018054604080516020600284861615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156109b15780601f10610986576101008083540402835291602001916109b1565b820191906000526020600020905b81548152906001019060200180831161099457829003601f168201915b505050505081565b6000336109c4611825565b15806109dd57506004546001600160a01b038281169116145b6109f95760405162461bcd60e51b815260040161074890612861565b6001600160a01b038416610a1f5760405162461bcd60e51b81526004016107489061274a565b6004546000906001600160a01b03163314610a3a5733610a3c565b305b6001600160a01b038082166000818152600d60209081526040808320948b1680845294909152908190208890555192935090917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610a9c9088906125a7565b60405180910390a3506001949350505050565b60005481565b60085460ff1681565b600083610ac9611825565b1580610ae257506004546001600160a01b038281169116145b610afe5760405162461bcd60e51b815260040161074890612861565b6001600160a01b0385166000908152600d60209081526040808320338452909152902054831115610b415760405162461bcd60e51b815260040161074890612b52565b610b4c858585611121565b610b685760405162461bcd60e51b8152600401610748906126c5565b6001600160a01b0385166000908152600c6020526040902054610b91908463ffffffff61204816565b6001600160a01b038087166000908152600c60205260408082209390935590861681522054610bc6908463ffffffff61202316565b6001600160a01b038086166000908152600c602090815260408083209490945583518085018552601981527f56616c7565206c6f776572207468616e20617070726f76616c00000000000000818301529289168252600d815283822033835290529190912054610c3d91859063ffffffff61208616565b6001600160a01b038087166000818152600d60209081526040808320338452909152908190209390935591519086169190600080516020612beb83398151915290610a9c9087906125a7565b600c6020526000908152604090205481565b6004546000906001600160a01b03163314610cc85760405162461bcd60e51b8152600401610748906128a8565b60085460ff16610cea5760405162461bcd60e51b81526004016107489061295e565b60008260ff1611610d0d5760405162461bcd60e51b815260040161074890612ae4565b600080805b600f54811015610dac57600f8181548110610d2957fe5b9060005260206000209060030201600001604051610d4791906124fc565b604051809103902087805190602001201415610d7457809150610d6d838660ff16612023565b9250610da4565b610da183600f8381548110610d8557fe5b600091825260209091206002600390920201015460ff16612023565b92505b600101610d12565b5085604051610dbb919061256c565b60405180910390207fdb5520a9f634155cff8e22a364080e6765f0d52cff4cbac09d4f8864c07d3c92868685604051610df693929190612620565b60405180910390a26064821115610e1f5760405162461bcd60e51b815260040161074890612995565b83600f8281548110610e2d57fe5b906000526020600020906003020160020160006101000a81548160ff021916908360ff16021790555084600f8281548110610e6457fe5b90600052602060002090600302016001019080519060200190610e889291906120d6565b5060019695505050505050565b600b8181548110610ea257fe5b600091825260209182902001805460408051601f60026000196101006001871615020190941693909304928301859004850281018501909152818152935090918301828280156109b15780601f10610986576101008083540402835291602001916109b1565b60025460ff1681565b6005546000906001600160a01b0316331480610f3757506004546001600160a01b031633145b610f535760405162461bcd60e51b8152600401610748906126fc565b60078290556040517f6c04066f6ede40cc1642c211ba9d18f1a096ccc84fb8d11be28ea6c3c6f68b3690610f889084906125a7565b60405180910390a1506001919050565b600854600090610100900460ff16610fc25760405162461bcd60e51b815260040161074890612a3c565b6006546001600160a01b0316331480610fe557506004546001600160a01b031633145b6110015760405162461bcd60e51b815260040161074890612a73565b3361100a611825565b158061102357506004546001600160a01b038281169116145b61103f5760405162461bcd60e51b815260040161074890612861565b6001600160a01b0384166000908152600c6020526040902054611068908463ffffffff61202316565b6001600160a01b0385166000908152600c602052604081209190915554611095908463ffffffff61202316565b60008190556040516001600160a01b038616917f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f916110d5918791612b89565b60405180910390a2836001600160a01b031660006001600160a01b0316600080516020612beb8339815191528560405161110f91906125a7565b60405180910390a35060019392505050565b60006001600160a01b03841661113957506000610925565b6001600160a01b03831661114f57506000610925565b60085462010000900460ff1661118157506001600160a01b0383166000908152600c6020526040902054811115610925565b6001600160a01b0384166000908152600e602052604090206001015460085460ff918216916301000000909104166111e0576001600160a01b0385166000908152600c602052604090205483118015906111d85750805b915050610925565b6001600160a01b038085166000908152600e60209081526040808320600101549389168352600c90915290205460ff90911690841180159061121f5750815b80156112285750805b9695505050505050565b6004546000906001600160a01b0316331461125f5760405162461bcd60e51b8152600401610748906128a8565b6001600160a01b0382166112855760405162461bcd60e51b815260040161074890612804565b6001600160a01b0382166000908152600e60205260408120906112a88282612154565b50600101805460ff191690556040517f24ee917fffe923f5cbaf9746ee4c53401b4cf82e794c88724e8a6946b5302ae590610f88908490612588565b6006546001600160a01b031681565b600854610100900460ff1681565b6004546000906001600160a01b0316331461132e5760405162461bcd60e51b8152600401610748906128a8565b50600a55600190565b600d60209081526000928352604080842090915290825290205481565b6004546000906001600160a01b031633146113815760405162461bcd60e51b8152600401610748906128a8565b600b805460018101825560009190915282516113c4917f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db9019060208501906120d6565b50600192915050565b60085462010000900460ff1681565b6001600160a01b03166000908152600c602052604090205490565b6008546301000000900460ff1681565b600e6020908152600091825260409182902080548351601f6002600019610100600186161502019093169290920491820184900484028101840190945280845290929183919083018282801561149e5780601f106114735761010080835404028352916020019161149e565b820191906000526020600020905b81548152906001019060200180831161148157829003601f168201915b5050506001909301549192505060ff1682565b6005546001600160a01b031681565b6004546000906001600160a01b031633146114ed5760405162461bcd60e51b8152600401610748906128a8565b600b54821061150e5760405162461bcd60e51b815260040161074890612648565b600b8054600019810190811061152057fe5b90600052602060002001600b838154811061153757fe5b90600052602060002001908054600181600116156101000203166002900461156092919061219b565b50600b80548061156c57fe5b6001900381819060005260206000200160006115889190612154565b9055506001919050565b6004546000906001600160a01b031633146115bf5760405162461bcd60e51b8152600401610748906128a8565b81516113c49060099060208501906120d6565b6003805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156109b15780601f10610986576101008083540402835291602001916109b1565b600033611638611825565b158061165157506004546001600160a01b038281169116145b61166d5760405162461bcd60e51b815260040161074890612861565b6006546001600160a01b031633148061169057506004546001600160a01b031633145b6116ac5760405162461bcd60e51b815260040161074890612a73565b6001600160a01b0384166116d25760405162461bcd60e51b81526004016107489061291d565b6000546116e5908463ffffffff61204816565b60009081556001600160a01b0385168152600c6020526040902054611710908463ffffffff61204816565b6001600160a01b0385166000818152600c6020526040808220939093559151600080516020612beb8339815191529061174a9087906125a7565b60405180910390a3836001600160a01b03167f49995e5dd6158cf69ad3e9777c46755a1a826a446c6416992167462dad033b2a8460005460405161178f929190612b89565b60405180910390a2341561181b576000846001600160a01b0316346040516117b69061182b565b60006040518083038185875af1925050503d80600081146117f3576040519150601f19603f3d011682016040523d82523d6000602084013e6117f8565b606091505b50509050806118195760405162461bcd60e51b8152600401610748906128ed565b505b5060019392505050565b60075443105b90565b600033611839611825565b158061185257506004546001600160a01b038281169116145b61186e5760405162461bcd60e51b815260040161074890612861565b6004546000906001600160a01b03163314611889573361188b565b305b9050611898818686611121565b6118b45760405162461bcd60e51b8152600401610748906126c5565b6001600160a01b0381166000908152600c60205260409020546118dd908563ffffffff61204816565b6001600160a01b038083166000908152600c60205260408082209390935590871681522054611912908563ffffffff61202316565b6001600160a01b038087166000818152600c60205260409081902093909355915190831690600080516020612beb83398151915290610a9c9088906125a7565b6004546000906001600160a01b0316331461197f5760405162461bcd60e51b8152600401610748906128a8565b60085460ff166119a15760405162461bcd60e51b815260040161074890612b1b565b600f5460ff8316106119c55760405162461bcd60e51b8152600401610748906129e7565b6060600f8360ff16815481106119d757fe5b6000918252602091829020600390910201805460408051601f6002600019610100600187161502019094169390930492830185900485028101850190915281815292830182828015611a6a5780601f10611a3f57610100808354040283529160200191611a6a565b820191906000526020600020905b815481529060010190602001808311611a4d57829003601f168201915b50505050509050600f6001600f805490500381548110611a8657fe5b9060005260206000209060030201600f8460ff1681548110611aa457fe5b906000526020600020906003020160008201816000019080546001816001161561010002031660029004611ad992919061219b565b5060018201816001019080546001816001161561010002031660029004611b0192919061219b565b506002918201549101805460ff191660ff909216919091179055600f80546000198101908110611b2d57fe5b60009182526020822060039091020190611b478282612154565b611b55600183016000612154565b50600201805460ff19169055600f805480611b6c57fe5b60008281526020812060001990920191600383020190611b8c8282612154565b611b9a600183016000612154565b50600201805460ff191690559055604051611bb690829061256c565b60405180910390207fdb5520a9f634155cff8e22a364080e6765f0d52cff4cbac09d4f8864c07d3c92600080604051611bf0929190612ac3565b60405180910390a250600192915050565b6005546000906001600160a01b0316331480611c2757506004546001600160a01b031633145b611c435760405162461bcd60e51b8152600401610748906126fc565b6001600160a01b038216611c695760405162461bcd60e51b81526004016107489061283b565b600480546001600160a01b0319166001600160a01b0384161790556040517f71614071b88dee5e0b2ae578a9dd7b2ebbe9ae832ba419dc0242cd065a290b6c90610f88908490612588565b600f8181548110611cc157fe5b60009182526020918290206003919091020180546040805160026001841615610100026000190190931692909204601f810185900485028301850190915280825291935091839190830182828015611d5a5780601f10611d2f57610100808354040283529160200191611d5a565b820191906000526020600020905b815481529060010190602001808311611d3d57829003601f168201915b505050505090806001018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611df85780601f10611dcd57610100808354040283529160200191611df8565b820191906000526020600020905b815481529060010190602001808311611ddb57829003601f168201915b5050506002909301549192505060ff1683565b6004546000906001600160a01b03163314611e385760405162461bcd60e51b8152600401610748906128a8565b600680546001600160a01b0319166001600160a01b0384161790556040517f5589a1df7a257347b14b97cb6fe06862c960ff64e9a0c2908632929098bb013090610f88908490612588565b60075481565b6009805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156109b15780601f10610986576101008083540402835291602001916109b1565b6001600160a01b038083166000908152600d60209081526040808320938516835292905220545b92915050565b600f5490565b6004546001600160a01b031681565b6004546000906001600160a01b03163314611f535760405162461bcd60e51b8152600401610748906128a8565b6001600160a01b038316611f795760405162461bcd60e51b815260040161074890612804565b611f81612210565b5060408051808201825283815260016020808301919091526001600160a01b0386166000908152600e8252929092208151805192938493611fc592849201906120d6565b50602091909101516001909101805460ff19169115159190911790556040517f97d33a7365e760e859a3453f70484ea24a4aeb75478205a52ac35174ead0ccf690612011908690612588565b60405180910390a15060019392505050565b6000828201838110156109255760405162461bcd60e51b81526004016107489061278c565b600061092583836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152505b600081848411156120aa5760405162461bcd60e51b815260040161074891906125b0565b505050900390565b60405180606001604052806060815260200160608152602001600060ff1681525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061211757805160ff1916838001178555612144565b82800160010185558215612144579182015b82811115612144578251825591602001919060010190612129565b50612150929150612228565b5090565b50805460018160011615610100020316600290046000825580601f1061217a5750612198565b601f0160209004906000526020600020908101906121989190612228565b50565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106121d45780548555612144565b8280016001018555821561214457600052602060002091601f016020900482015b828111156121445782548255916001019190600101906121f5565b60408051808201909152606081526000602082015290565b61182b91905b80821115612150576000815560010161222e565b600082601f830112612252578081fd5b813567ffffffffffffffff80821115612269578283fd5b604051601f8301601f191681016020018281118282101715612289578485fd5b6040528281529250828483016020018610156122a457600080fd5b8260208601602083013760006020848301015250505092915050565b803560ff81168114611f0b57600080fd5b6000602082840312156122e2578081fd5b813561092581612bd5565b600080604083850312156122ff578081fd5b823561230a81612bd5565b946020939093013593505050565b6000806040838503121561232a578182fd5b823561233581612bd5565b9150602083013561234581612bd5565b809150509250929050565b600080600060608486031215612364578081fd5b833561236f81612bd5565b9250602084013561237f81612bd5565b929592945050506040919091013590565b600080604083850312156123a2578182fd5b82356123ad81612bd5565b9150602083013567ffffffffffffffff8111156123c8578182fd5b6123d485828601612242565b9150509250929050565b600080604083850312156122ff578182fd5b600060208284031215612401578081fd5b5035919050565b600060208284031215612419578081fd5b813567ffffffffffffffff81111561242f578182fd5b61243b84828501612242565b949350505050565b600080600060608486031215612457578283fd5b833567ffffffffffffffff8082111561246e578485fd5b61247a87838801612242565b9450602086013591508082111561248f578384fd5b5061249c86828701612242565b9250506124ac85604086016122c0565b90509250925092565b6000602082840312156124c6578081fd5b61092583836122c0565b600081518084526124e8816020860160208601612ba5565b601f01601f19169290920160200192915050565b600080835460018082166000811461251b576001811461253257612561565b60ff198316865260028304607f1686019350612561565b600283048786526020808720875b838110156125595781548a820152908501908201612540565b505050860193505b509195945050505050565b6000825161257e818460208701612ba5565b9190910192915050565b6001600160a01b0391909116815260200190565b901515815260200190565b90815260200190565b60006020825261092560208301846124d0565b6000604082526125d660408301856124d0565b905082151560208301529392505050565b6000606082526125fa60608301866124d0565b828103602084015261260c81866124d0565b91505060ff83166040830152949350505050565b60006060825261263360608301866124d0565b60ff9490941660208301525060400152919050565b602080825260169082015275092dcecc2d8d2c840e0d8c2e8ccdee4da40d2dcc8caf60531b604082015260600190565b6020808252602d908201527f546f74616c20617373657473206e756d6265722063616e6e6f7420626520686960408201526c067686572207468616e2031303609c1b606082015260800190565b6020808252601a908201527f496e76616c6964205472616e73666572204f7065726174696f6e000000000000604082015260600190565b6020808252602e908201527f4f6e6c792061646d696e206f7220626f6172642063616e20706572666f726d2060408201526d3a3434b99037b832b930ba34b7b760911b606082015260800190565b60208082526022908201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604082015261737360f01b606082015260800190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526021908201527f416e2061737365742063616e6e6f742062652061737369676e656420747769636040820152606560f81b606082015260800190565b60208082526018908201527f496e76616c696420696e766573746f7220616464726573730000000000000000604082015260600190565b6020808252600c908201526b4e756c6c206164647265737360a01b604082015260600190565b60208082526027908201527f436f6e7472616374206973206c6f636b65642065786365707420666f72207468604082015266329030b236b4b760c91b606082015260800190565b60208082526025908201527f4f6e6c792061646d696e2063616e20706572666f726d2074686973206f70657260408201526430ba34b7b760d91b606082015260800190565b60208082526016908201527522ba3432b9103a3930b739b332b9103330b4b632b21760511b604082015260600190565b60208082526021908201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736040820152607360f81b606082015260800190565b6020808252601a908201527f43616e6e6f74206368616e676520617373657420616d6f756e74000000000000604082015260600190565b60208082526032908201527f46756e642061737365747320746f74616c2070657263656e74616765206d7573604082015271074206265206c657373207468616e203130360741b606082015260800190565b60208082526035908201527f496e76616c696420617373657420696e646578206e756d6265722e2047726561604082015274746572207468616e20746f74616c2061737365747360581b606082015260800190565b60208082526019908201527f546f6b656e206d696e74696e672069732064697361626c656400000000000000604082015260600190565b60208082526030908201527f4f6e6c79206d616e61676572206f722061646d696e2063616e20706572666f7260408201526f36903a3434b99037b832b930ba34b7b760811b606082015260800190565b606080825260009082015260ff929092166020830152604082015260800190565b6020808252601c908201527f43616e6e6f7420736574207a65726f20617373657420616d6f756e7400000000604082015260600190565b6020808252601d908201527f43616e6e6f74206368616e676520617373657420706f7274666f6c696f000000604082015260600190565b60208082526019908201527f56616c756520696e666f726d656420697320696e76616c696400000000000000604082015260600190565b918252602082015260400190565b60ff91909116815260200190565b60005b83811015612bc0578181015183820152602001612ba8565b83811115612bcf576000848401525b50505050565b6001600160a01b038116811461219857600080fdfeddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa264697066735822122087c4fbd1b419a6e7c40ccbbfa6dfb33151f46f9229cd3848014d1b69cdbde30a64736f6c63430006060033
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.