Contract 0x43C7AB3e47adc06Fc87692a65A68b04408b4092D

 
 
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x987ba4fef8b54ef67dc2154283c8b096f31245c7806e0624a51e7fdf6fb24b6d0x60806040227475462021-12-20 11:39:0539 days 14 hrs ago0xaef68c6b81fd82e6d8292524d0723f9dae201b36 IN  Create: MecenasMultisignWalletFactory0 MATIC0.0678398430
[ Download CSV Export 
Latest 1 internal transaction
Parent Txn Hash Block From To Value
0xa97a00d3349b69a1619c16f1330588d7567478ac4007552efa15f5ce16227e46227478952021-12-20 11:51:0339 days 14 hrs ago 0x43c7ab3e47adc06fc87692a65a68b04408b4092d  Contract Creation0 MATIC
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
MecenasMultisignWalletFactory

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity Multiple files format)

File 1 of 3: MecenasMultisignWalletFactory.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./MecenasMultisignWallet.sol";


contract MecenasMultisignWalletFactory {

    address public constant EMPTY_ADDRESS_FACTORY = address(0);

    struct Wallet {
        MecenasMultisignWallet wallet;
        address pool;
        address underlying;
    }
    
    uint public counterwallets;
    address public factoryowner;
    bool public lockfactory;
        
    mapping(address => Wallet[]) public OwnerWallets;
    Wallet[] public FactoryWallets;
     
    event ChildCreated(address indexed childAddress, address indexed pooladdress, address indexed underlyingaddress);
    event ChangeFactoryOwner(address indexed oldowner, address indexed newowner);
    event ChangeFactoryLock(bool oldlock, bool newlock);


    constructor() {
        factoryowner = msg.sender;
    }    

    
    // this function changes the factory owner address

    function changeowner(address _newowner) public {
        require(_newowner != EMPTY_ADDRESS_FACTORY && msg.sender == factoryowner);
        address oldowner = factoryowner;
        factoryowner = _newowner;
    
        emit ChangeFactoryOwner(oldowner, factoryowner);
    }


    // this function locks and unlocks de factory 
    // false = unlock
    // true = lock
    
    function changelockfactory(bool _newlock) public {
        require(_newlock == true || _newlock == false);
        require(msg.sender == factoryowner);
        bool oldlock = lockfactory;
        lockfactory = _newlock;
    
        emit ChangeFactoryLock(oldlock, lockfactory);
    }


    // this function creates a new Mecenas Multisign Wallet

    function newMecenasWallet(address _owneraddress, address _pooladdress, address _underlyingaddress) external returns (address) {
        require(lockfactory == false);
        require(_pooladdress != EMPTY_ADDRESS_FACTORY && _underlyingaddress != EMPTY_ADDRESS_FACTORY && msg.sender != EMPTY_ADDRESS_FACTORY);
        
        counterwallets++;
    
        MecenasMultisignWallet newwallet = new MecenasMultisignWallet(_owneraddress, _pooladdress, _underlyingaddress);
        
        FactoryWallets.push(Wallet(newwallet, _pooladdress, _underlyingaddress));
        OwnerWallets[_owneraddress].push(Wallet(MecenasMultisignWallet(newwallet), address(_pooladdress), address(_underlyingaddress)));

        emit ChildCreated(address(newwallet), _pooladdress, _underlyingaddress);

        return address(newwallet);
    }
    
    
    
    // this function returns an array of struct of wallets created by owner

    function getOwnerWallets(address _account) external view returns (Wallet[] memory) {
      return OwnerWallets[_account];
    } 


    // this function returns an array of struct of wallets created
    
    function getTotalWallets() external view returns (Wallet[] memory) {
      return FactoryWallets;
    }

}

File 2 of 3: MecenasMultisignWallet.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./ReentrancyGuard.sol";


interface MecenasPool {

    function withdrawyield(uint _amount, uint _flag) external;
    function withdrawdonations(uint _amount) external;
}

interface ERC20 {

    function balanceOf(address account) external view returns (uint256);
    function transfer(address recipient, uint256 amount) external returns (bool);
    function allowance(address owner, address spender) external view returns (uint256);
    function approve(address spender, uint256 amount) external returns (bool);
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
    function decimals() external view returns (uint8);
    function symbol() external view returns (string memory);
}


contract MecenasMultisignWallet is ReentrancyGuard {

    address public constant EMPTY_ADDRESS = address(0);

    ERC20 public walletunderlying;
    MecenasPool public walletpool;

    address public owner;
    
    struct OwnerState {
        address thesigner;
        uint thestate;
    }

    OwnerState[] public owners;

    mapping(address => uint) public signers;
    mapping(address => uint) public signersindex;
    uint public threshold;
    uint public ownerscounter;

    struct Transaction {
        uint datecreation;
        address creator;
        uint transtype;
        uint amount;
        address to;
        uint signaturesCount;
        uint status;
        uint dateexecution;
        uint signthreshold;
}


    mapping (address => mapping(uint => uint)) public signatures;


    Transaction[] public pendingtransactions;

    event PendingTransactionAdded(address indexed from, uint _type, uint amount, address indexed to);
    event TransactionSigned(address indexed from, uint transactionid);
    event SignatureRevoked(address indexed from, uint transactionid);
    event TransactionDeleted(address indexed from, uint transactionid);
    event TransferUnderlying(uint transactionid, address indexed to, uint amount);
    event WithdrawUnderlying(uint transactionid, uint amount);
    event SignerAdded(uint transactionid, address indexed signer);
    event SignerRemoved(uint transactionid, address indexed signer);
    event ThresholdChanged(uint transactionid, uint numbersignature);


    constructor(address _owner, address _pooladdress, address _underlyingaddress) {
        require(_owner != EMPTY_ADDRESS);
        owner = _owner;
        signers[_owner] = 1;
        owners.push(OwnerState(_owner, 1));
        signersindex[_owner] = owners.length - 1;
        ownerscounter += 1;
        threshold = 1;
        walletpool = MecenasPool(_pooladdress);
        walletunderlying = ERC20(_underlyingaddress);
    }


    // this function adds a pending Transaction
    // _transyype 1 = whithdraw interest
    // _transyype 2 = whithdraw reserves
    // _transyype 3 = whithdraw donations
    // _transyype 4 = transfer underlying
    // _transyype 5 = add a new signer
    // _transyype 6 = change the threshold signatures
    // _transyype 7 = remove signer

    function addPendingTransaction(uint _transtype, uint _amount, address _to) external {
        require(signers[msg.sender] == 1);
        require(_amount > 0);
        require(_transtype == 1 || _transtype == 2 || _transtype == 3 || _transtype == 4 || _transtype == 5 
                || _transtype == 6 || _transtype == 7);

        if(_transtype == 4 || _transtype == 5 || _transtype == 7) {
            require(_to != EMPTY_ADDRESS);
        }

        if(_transtype == 5) {
            require(signers[_to] != 1);
        }

        if(_transtype == 6) {
            require(_amount > 0);
            require(_amount <= ownerscounter);
            require(_amount != threshold);
        }

        if(_transtype == 7) {
            require(signers[_to] == 1);
            require(ownerscounter > 1);
        }

        pendingtransactions.push(Transaction(block.timestamp, msg.sender, _transtype, _amount, address(_to), 0, 0, 0, threshold));

        uint idtransaction = pendingtransactions.length - 1;
        signTransaction(idtransaction);
    
        emit PendingTransactionAdded(msg.sender, _transtype, _amount, _to);
    }


    // this function signs a transaction and executes it if transaction threshold is reached

    function signTransaction(uint index) public nonReentrant {
            require(signers[msg.sender] == 1);
            require(index <= pendingtransactions.length - 1);
            require(signatures[msg.sender][index] == 0);
            require(pendingtransactions[index].signaturesCount < pendingtransactions[index].signthreshold);
            require(pendingtransactions[index].status == 0);
            
            pendingtransactions[index].signaturesCount += 1;
            signatures[msg.sender][index] = 1;

            if(pendingtransactions[index].signaturesCount == pendingtransactions[index].signthreshold) {

                if(pendingtransactions[index].transtype == 1 || pendingtransactions[index].transtype == 2) {
                    walletpool.withdrawyield(pendingtransactions[index].amount, pendingtransactions[index].transtype);
                    emit WithdrawUnderlying(index, pendingtransactions[index].amount);
                }

                if(pendingtransactions[index].transtype == 3) {
                    walletpool.withdrawdonations(pendingtransactions[index].amount);
                    emit WithdrawUnderlying(index, pendingtransactions[index].amount);
                }    
                    
                if(pendingtransactions[index].transtype == 4) {
                    require(walletunderlying.balanceOf(address(this)) >= pendingtransactions[index].amount); 
                    require(walletunderlying.transfer(pendingtransactions[index].to, pendingtransactions[index].amount) == true);
                    emit TransferUnderlying(index, pendingtransactions[index].to, pendingtransactions[index].amount);
                }
            
                if(pendingtransactions[index].transtype == 5) {
                    require(signers[pendingtransactions[index].to] != 1);
                    ownerscounter += 1;
                    
                    if(signers[pendingtransactions[index].to] == 0) {
                        owners.push(OwnerState(pendingtransactions[index].to, 1));
                        signersindex[pendingtransactions[index].to] = owners.length - 1;
                    }
                    
                    if(signers[pendingtransactions[index].to] == 2) {
                        uint theindex = signersindex[pendingtransactions[index].to];
                        owners[theindex].thestate = 1;
                    }

                    signers[pendingtransactions[index].to] = 1;
                
                    emit SignerAdded(index, pendingtransactions[index].to);
                }

                if(pendingtransactions[index].transtype == 6) {
                    require(pendingtransactions[index].amount > 0);
                    require(pendingtransactions[index].amount <= ownerscounter);
                    require(pendingtransactions[index].amount != threshold);

                    threshold = pendingtransactions[index].amount;
                
                    emit ThresholdChanged(index, pendingtransactions[index].amount);
                }

                if(pendingtransactions[index].transtype == 7) {
                    require(signers[pendingtransactions[index].to] == 1);
                    require(ownerscounter > 1);

                    signers[pendingtransactions[index].to] = 2;
                    ownerscounter -= 1;
                    uint theindex = signersindex[pendingtransactions[index].to];
                    owners[theindex].thestate = 2;

                    if(threshold > ownerscounter) {
                    threshold -= 1;
                    }
                
                    emit SignerRemoved(index, pendingtransactions[index].to);
                }    

                pendingtransactions[index].status = 1;
                pendingtransactions[index].dateexecution = block.timestamp;
            }    
    
        emit TransactionSigned(msg.sender, index);
    }


    // this function revokes a previous signature

    function revokeSignature(uint index) external nonReentrant {
        require(signers[msg.sender] == 1);
        require(index <= pendingtransactions.length - 1);
        require(pendingtransactions[index].status == 0);
        require(signatures[msg.sender][index] == 1);

        pendingtransactions[index].signaturesCount -= 1;
        signatures[msg.sender][index] = 0;

        emit SignatureRevoked(msg.sender, index);
}


    // this function removes a pending transaction

    function deleteTransaction(uint index) external nonReentrant {
        require(signers[msg.sender] == 1);
        require(index <= pendingtransactions.length - 1);
        require(pendingtransactions[index].status == 0);

        pendingtransactions[index].status = 2;
        pendingtransactions[index].dateexecution = block.timestamp;
    
        emit TransactionDeleted(msg.sender, index);
    }


    // this function returns an array of pending transactions

    function getPendingTransactions() external view returns (Transaction[] memory) {
        return pendingtransactions;
    }


    // this function returns the wallet balance of the underlying 

    function getBalanceWallet() external view returns (uint) {
        return walletunderlying.balanceOf(address(this));
    }


    // this function returns the length of the pending transactions array

    function getPendingTransactionsLength() external view returns (uint) {
        return pendingtransactions.length;
    }


    // this function returns an array of wallet owners 

    function getOwners() external view returns (OwnerState[] memory) {
    return owners;
    }
  
}

File 3 of 3: ReentrancyGuard.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"oldlock","type":"bool"},{"indexed":false,"internalType":"bool","name":"newlock","type":"bool"}],"name":"ChangeFactoryLock","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldowner","type":"address"},{"indexed":true,"internalType":"address","name":"newowner","type":"address"}],"name":"ChangeFactoryOwner","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"childAddress","type":"address"},{"indexed":true,"internalType":"address","name":"pooladdress","type":"address"},{"indexed":true,"internalType":"address","name":"underlyingaddress","type":"address"}],"name":"ChildCreated","type":"event"},{"inputs":[],"name":"EMPTY_ADDRESS_FACTORY","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"FactoryWallets","outputs":[{"internalType":"contract MecenasMultisignWallet","name":"wallet","type":"address"},{"internalType":"address","name":"pool","type":"address"},{"internalType":"address","name":"underlying","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"OwnerWallets","outputs":[{"internalType":"contract MecenasMultisignWallet","name":"wallet","type":"address"},{"internalType":"address","name":"pool","type":"address"},{"internalType":"address","name":"underlying","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_newlock","type":"bool"}],"name":"changelockfactory","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newowner","type":"address"}],"name":"changeowner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"counterwallets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"factoryowner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"getOwnerWallets","outputs":[{"components":[{"internalType":"contract MecenasMultisignWallet","name":"wallet","type":"address"},{"internalType":"address","name":"pool","type":"address"},{"internalType":"address","name":"underlying","type":"address"}],"internalType":"struct MecenasMultisignWalletFactory.Wallet[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalWallets","outputs":[{"components":[{"internalType":"contract MecenasMultisignWallet","name":"wallet","type":"address"},{"internalType":"address","name":"pool","type":"address"},{"internalType":"address","name":"underlying","type":"address"}],"internalType":"struct MecenasMultisignWalletFactory.Wallet[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockfactory","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owneraddress","type":"address"},{"internalType":"address","name":"_pooladdress","type":"address"},{"internalType":"address","name":"_underlyingaddress","type":"address"}],"name":"newMecenasWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"}]

608060405234801561001057600080fd5b50600180546001600160a01b03191633179055612790806100326000396000f3fe608060405234801561001057600080fd5b50600436106100a95760003560e01c8063a60e1c2b11610071578063a60e1c2b1461014b578063bba4c1911461015e578063cb4a93681461017e578063d8ee94b1146101a2578063dd67e387146101b9578063f5f50eb1146101cc57600080fd5b80635202339a146100ae578063662e4ee4146100f0578063751c8b1a14610105578063789a7b0b1461013057806385ffa14614610138575b600080fd5b6100c16100bc3660046107af565b6101d4565b604080516001600160a01b03948516815292841660208401529216918101919091526060015b60405180910390f35b6101036100fe3660046107e4565b610216565b005b600154610118906001600160a01b031681565b6040516001600160a01b0390911681526020016100e7565b610118600081565b610118610146366004610806565b610293565b610103610159366004610849565b61058e565b61017161016c3660046107e4565b61062f565b6040516100e7919061086b565b60015461019290600160a01b900460ff1681565b60405190151581526020016100e7565b6101ab60005481565b6040519081526020016100e7565b6100c16101c73660046108d3565b6106cc565b61017161071b565b600381815481106101e457600080fd5b60009182526020909120600390910201805460018201546002909201546001600160a01b039182169350918116911683565b6001600160a01b0381161580159061023857506001546001600160a01b031633145b61024157600080fd5b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f7eee5cbc033ec172b73198088b64e108dc7242d7d8722dbdd10945c3c05d4c3f90600090a35050565b600154600090600160a01b900460ff16156102ad57600080fd5b6001600160a01b038316158015906102cd57506001600160a01b03821615155b80156102d857503315155b6102e157600080fd5b6000805490806102f0836108fd565b91905055506000848484604051610306906107a2565b6001600160a01b03938416815291831660208301529091166040820152606001604051809103906000f080158015610342573d6000803e3d6000fd5b50905060036040518060600160405280836001600160a01b03168152602001866001600160a01b03168152602001856001600160a01b0316815250908060018154018082558091505060019003906000526020600020906003020160009091909190915060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160010160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060408201518160020160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550505060026000866001600160a01b03166001600160a01b031681526020019081526020016000206040518060600160405280836001600160a01b03168152602001866001600160a01b03168152602001856001600160a01b0316815250908060018154018082558091505060019003906000526020600020906003020160009091909190915060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160010160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060408201518160020160006101000a8154816001600160a01b0302191690836001600160a01b031602179055505050826001600160a01b0316846001600160a01b0316826001600160a01b03167f07f41cdea73572171c6139ef3062c09b665ecef958bcab76fae46bc89a24dc0b60405160405180910390a4949350505050565b6001811515148061059d575080155b6105a657600080fd5b6001546001600160a01b031633146105bd57600080fd5b60018054821515600160a01b90810260ff60a01b198316179283905560405160ff928290048316937fbe7d1cb79f3095a7130e4c3390d628e846d218e281792d2ccfbc7611f21d44cd936106239386939204169091151582521515602082015260400190565b60405180910390a15050565b6001600160a01b0381166000908152600260209081526040808320805482518185028101850190935280835260609492939192909184015b828210156106c1576000848152602090819020604080516060810182526003860290920180546001600160a01b03908116845260018083015482168587015260029092015416918301919091529083529092019101610667565b505050509050919050565b600260205281600052604060002081815481106106e857600080fd5b60009182526020909120600390910201805460018201546002909201546001600160a01b03918216945091811692501683565b60606003805480602002602001604051908101604052809291908181526020016000905b82821015610799576000848152602090819020604080516060810182526003860290920180546001600160a01b0390811684526001808301548216858701526002909201541691830191909152908352909201910161073f565b50505050905090565b611e348061092783390190565b6000602082840312156107c157600080fd5b5035919050565b80356001600160a01b03811681146107df57600080fd5b919050565b6000602082840312156107f657600080fd5b6107ff826107c8565b9392505050565b60008060006060848603121561081b57600080fd5b610824846107c8565b9250610832602085016107c8565b9150610840604085016107c8565b90509250925092565b60006020828403121561085b57600080fd5b813580151581146107ff57600080fd5b602080825282518282018190526000919060409081850190868401855b828110156108c657815180516001600160a01b0390811686528782015181168887015290860151168585015260609093019290850190600101610888565b5091979650505050505050565b600080604083850312156108e657600080fd5b6108ef836107c8565b946020939093013593505050565b600060001982141561091f57634e487b7160e01b600052601160045260246000fd5b506001019056fe60806040523480156200001157600080fd5b5060405162001e3438038062001e3483398101604081905262000034916200019d565b60016000556001600160a01b0383166200004d57600080fd5b600380546001600160a01b038086166001600160a01b031992831681179093556000838152600560209081526040808320600190819055815180830190925295815290810185815260048054808801825593819052915160029093027f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b81018054949095169390951692909217909255517f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19c9092019190915554620001139190620001fd565b6001600160a01b03841660009081526006602052604081209190915560088054600192906200014490849062000217565b909155505060016007819055600280546001600160a01b03199081166001600160a01b0395861617909155815416919092161790555062000232565b80516001600160a01b03811681146200019857600080fd5b919050565b600080600060608486031215620001b357600080fd5b620001be8462000180565b9250620001ce6020850162000180565b9150620001de6040850162000180565b90509250925092565b634e487b7160e01b600052601160045260246000fd5b600082821015620002125762000212620001e7565b500390565b600082198211156200022d576200022d620001e7565b500190565b611bf280620002426000396000f3fe608060405234801561001057600080fd5b50600436106101205760003560e01c806363d44de6116100ad578063a0e67e2b11610071578063a0e67e2b146102c8578063bc6f4d8e146102dd578063d11db83f146102fd578063e3faba3314610312578063eb39c3af1461032557600080fd5b806363d44de6146101f2578063736c0d5b146102575780638da5cb5b146102775780638f3ca92c146102a25780639d92f4df146102b557600080fd5b806340c5f783116100f457806340c5f783146101bd57806342cde4e8146101c657806356d09089146101cf5780635d9ec210146101d75780635e53f29e146101ea57600080fd5b8062e9c00614610125578063025e7c271461013a57806325d97bb6146101715780633da1f79a146101aa575b600080fd5b610138610133366004611948565b61032d565b005b61014d610148366004611948565b610463565b604080516001600160a01b0390931683526020830191909152015b60405180910390f35b61019c61017f36600461197d565b600960209081526000928352604080842090915290825290205481565b604051908152602001610168565b6101386101b8366004611948565b61049b565b61019c60085481565b61019c60075481565b61019c6105d6565b6101386101e5366004611948565b610657565b600a5461019c565b610205610200366004611948565b61141f565b60408051998a526001600160a01b0398891660208b0152890196909652606088019490945294909116608086015260a085015260c084019290925260e083019190915261010082015261012001610168565b61019c6102653660046119a7565b60056020526000908152604090205481565b60035461028a906001600160a01b031681565b6040516001600160a01b039091168152602001610168565b60015461028a906001600160a01b031681565b60025461028a906001600160a01b031681565b6102d0611486565b60405161016891906119c9565b61019c6102eb3660046119a7565b60066020526000908152604090205481565b6103056114fb565b6040516101689190611a21565b610138610320366004611aba565b6115b5565b61028a600081565b600260005414156103595760405162461bcd60e51b815260040161035090611aef565b60405180910390fd5b600260009081553381526005602052604090205460011461037957600080fd5b600a5461038890600190611b3c565b81111561039457600080fd5b600a81815481106103a7576103a7611b53565b9060005260206000209060090201600601546000146103c557600080fd5b6002600a82815481106103da576103da611b53565b90600052602060002090600902016006018190555042600a828154811061040357610403611b53565b906000526020600020906009020160070181905550336001600160a01b03167f4fd28eb460242897d68bda6a7b9e31ba52539188f887613e331fccb55a794dcf8260405161045391815260200190565b60405180910390a2506001600055565b6004818154811061047357600080fd5b6000918252602090912060029091020180546001909101546001600160a01b03909116915082565b600260005414156104be5760405162461bcd60e51b815260040161035090611aef565b60026000908155338152600560205260409020546001146104de57600080fd5b600a546104ed90600190611b3c565b8111156104f957600080fd5b600a818154811061050c5761050c611b53565b90600052602060002090600902016006015460001461052a57600080fd5b33600090815260096020908152604080832084845290915290205460011461055157600080fd5b6001600a828154811061056657610566611b53565b906000526020600020906009020160050160008282546105869190611b3c565b909155505033600081815260096020908152604080832085845282528083209290925590518381527fc789392d310b05f9af6a1259598659baa19dcd7355adcddc4c0a307f5ec5f8289101610453565b6001546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b15801561061a57600080fd5b505afa15801561062e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106529190611b69565b905090565b6002600054141561067a5760405162461bcd60e51b815260040161035090611aef565b600260009081553381526005602052604090205460011461069a57600080fd5b600a546106a990600190611b3c565b8111156106b557600080fd5b336000908152600960209081526040808320848452909152902054156106da57600080fd5b600a81815481106106ed576106ed611b53565b906000526020600020906009020160080154600a828154811061071257610712611b53565b9060005260206000209060090201600501541061072e57600080fd5b600a818154811061074157610741611b53565b90600052602060002090600902016006015460001461075f57600080fd5b6001600a828154811061077457610774611b53565b906000526020600020906009020160050160008282546107949190611b82565b9091555050336000908152600960209081526040808320848452909152902060019055600a8054829081106107cb576107cb611b53565b906000526020600020906009020160080154600a82815481106107f0576107f0611b53565b90600052602060002090600902016005015414156113ed57600a818154811061081b5761081b611b53565b9060005260206000209060090201600201546001148061085f5750600a818154811061084957610849611b53565b9060005260206000209060090201600201546002145b1561098457600254600a80546001600160a01b039092169163882ffd2c91908490811061088e5761088e611b53565b906000526020600020906009020160030154600a84815481106108b3576108b3611b53565b9060005260206000209060090201600201546040518363ffffffff1660e01b81526004016108eb929190918252602082015260400190565b600060405180830381600087803b15801561090557600080fd5b505af1158015610919573d6000803e3d6000fd5b505050507fced0f5cc0b4871b418daef75a22185b9aba2d9f1427d1fe63008f793b035df7d81600a838154811061095257610952611b53565b90600052602060002090600902016003015460405161097b929190918252602082015260400190565b60405180910390a15b600a818154811061099757610997611b53565b90600052602060002090600902016002015460031415610aa457600254600a80546001600160a01b039092169163954e72979190849081106109db576109db611b53565b9060005260206000209060090201600301546040518263ffffffff1660e01b8152600401610a0b91815260200190565b600060405180830381600087803b158015610a2557600080fd5b505af1158015610a39573d6000803e3d6000fd5b505050507fced0f5cc0b4871b418daef75a22185b9aba2d9f1427d1fe63008f793b035df7d81600a8381548110610a7257610a72611b53565b906000526020600020906009020160030154604051610a9b929190918252602082015260400190565b60405180910390a15b600a8181548110610ab757610ab7611b53565b90600052602060002090600902016002015460041415610d2857600a8181548110610ae457610ae4611b53565b60009182526020909120600990910201600301546001546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b158015610b3b57600080fd5b505afa158015610b4f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b739190611b69565b1015610b7e57600080fd5b600154600a80546001600160a01b039092169163a9059cbb919084908110610ba857610ba8611b53565b906000526020600020906009020160040160009054906101000a90046001600160a01b0316600a8481548110610be057610be0611b53565b60009182526020909120600360099092020101546040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b158015610c3a57600080fd5b505af1158015610c4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c729190611b9a565b1515600114610c8057600080fd5b600a8181548110610c9357610c93611b53565b906000526020600020906009020160040160009054906101000a90046001600160a01b03166001600160a01b03167faf08d11015498824e71886e4beeda2a0bf5c6a0c352c6c088838b107bb4444ec82600a8481548110610cf657610cf6611b53565b906000526020600020906009020160030154604051610d1f929190918252602082015260400190565b60405180910390a25b600a8181548110610d3b57610d3b611b53565b906000526020600020906009020160020154600514156110515760056000600a8381548110610d6c57610d6c611b53565b60009182526020808320600460099093020191909101546001600160a01b0316835282019290925260400190205460011415610da757600080fd5b600160086000828254610dba9190611b82565b9250508190555060056000600a8381548110610dd857610dd8611b53565b60009182526020808320600460099093020191909101546001600160a01b03168352820192909252604001902054610edf5760046040518060400160405280600a8481548110610e2a57610e2a611b53565b6000918252602080832060046009909302018201546001600160a01b0390811685526001948201859052865480860188559684529281902085516002909702018054969093166001600160a01b031990961695909517825592909301519281019290925554610e999190611b3c565b60066000600a8481548110610eb057610eb0611b53565b60009182526020808320600460099093020191909101546001600160a01b031683528201929092526040019020555b60056000600a8381548110610ef657610ef6611b53565b60009182526020808320600460099093020191909101546001600160a01b0316835282019290925260400190205460021415610fa357600060066000600a8481548110610f4557610f45611b53565b6000918252602080832060046009909302018201546001600160a01b03168452830193909352604090910190205481549092506001919083908110610f8c57610f8c611b53565b906000526020600020906002020160010181905550505b600160056000600a8481548110610fbc57610fbc611b53565b60009182526020808320600460099093020191909101546001600160a01b03168352820192909252604001902055600a805482908110610ffe57610ffe611b53565b6000918252602091829020600990910201600401546040518381526001600160a01b03909116917f599c236efc4262ea022de8ec69e20c5bf0c0907c98fedf8cafc04d72e6bca6a3910160405180910390a25b600a818154811061106457611064611b53565b906000526020600020906009020160020154600614156111a7576000600a828154811061109357611093611b53565b906000526020600020906009020160030154116110af57600080fd5b600854600a82815481106110c5576110c5611b53565b90600052602060002090600902016003015411156110e257600080fd5b600754600a82815481106110f8576110f8611b53565b906000526020600020906009020160030154141561111557600080fd5b600a818154811061112857611128611b53565b9060005260206000209060090201600301546007819055507f3164947cf0f49f08dd0cd80e671535b1e11590d347c55dcaa97ba3c24a96b33a81600a838154811061117557611175611b53565b90600052602060002090600902016003015460405161119e929190918252602082015260400190565b60405180910390a15b600a81815481106111ba576111ba611b53565b906000526020600020906009020160020154600714156113995760056000600a83815481106111eb576111eb611b53565b60009182526020808320600460099093020191909101546001600160a01b0316835282019290925260400190205460011461122557600080fd5b60016008541161123457600080fd5b600260056000600a848154811061124d5761124d611b53565b60009182526020808320600460099093020191909101546001600160a01b031683528201929092526040018120919091556008805460019290611291908490611b3c565b92505081905550600060066000600a84815481106112b1576112b1611b53565b6000918252602080832060046009909302018201546001600160a01b031684528301939093526040909101902054815490925060029190839081106112f8576112f8611b53565b90600052602060002090600202016001018190555060085460075411156113325760016007600082825461132c9190611b3c565b90915550505b600a828154811061134557611345611b53565b6000918252602091829020600990910201600401546040518481526001600160a01b03909116917f46532f1b82ef225ceced2d5222b6ef68b2238a6c344d7fb59dd476850a9cba72910160405180910390a2505b6001600a82815481106113ae576113ae611b53565b90600052602060002090600902016006018190555042600a82815481106113d7576113d7611b53565b9060005260206000209060090201600701819055505b60405181815233907fac63e7e1dc16bccf900879686e74ca33eeb175b670e3aaa9d7e4ccf3781b7a7a90602001610453565b600a818154811061142f57600080fd5b60009182526020909120600990910201805460018201546002830154600384015460048501546005860154600687015460078801546008909801549698506001600160a01b03958616979496939590921693909289565b60606004805480602002602001604051908101604052809291908181526020016000905b828210156114f2576000848152602090819020604080518082019091526002850290910180546001600160a01b031682526001908101548284015290835290920191016114aa565b50505050905090565b6060600a805480602002602001604051908101604052809291908181526020016000905b828210156114f2576000848152602090819020604080516101208101825260098602909201805483526001808201546001600160a01b03908116858701526002830154938501939093526003820154606085015260048201549092166080840152600581015460a0840152600681015460c0840152600781015460e084015260080154610100830152908352909201910161151f565b336000908152600560205260409020546001146115d157600080fd5b600082116115de57600080fd5b82600114806115ed5750826002145b806115f85750826003145b806116035750826004145b8061160e5750826005145b806116195750826006145b806116245750826007145b61162d57600080fd5b826004148061163c5750826005145b806116475750826007145b1561165f576001600160a01b03811661165f57600080fd5b826005141561168e576001600160a01b0381166000908152600560205260409020546001141561168e57600080fd5b82600614156116c257600082116116a457600080fd5b6008548211156116b357600080fd5b6007548214156116c257600080fd5b82600714156116ff576001600160a01b0381166000908152600560205260409020546001146116f057600080fd5b6001600854116116ff57600080fd5b60408051610120810182524281523360208201908152918101858152606082018581526001600160a01b0385811660808501908152600060a0860181815260c0870182815260e088018381526007546101008a01908152600a8054600180820183558288529b517fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a86009909202918201559b517fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a98d0180546001600160a01b0319908116928b1692909217905599517fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2aa8d015597517fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2ab8c015594517fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2ac8b018054909916961695909517909655517fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2ad88015593517fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2ae87015590517fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2af860155517fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2b09094019390935591546118f19190611b3c565b90506118fc81610657565b60408051858152602081018590526001600160a01b0384169133917f6eac6e0efc809fb726df6f816ccf0d78d1a23f2074d1de6eb781bff3d4ed283a910160405180910390a350505050565b60006020828403121561195a57600080fd5b5035919050565b80356001600160a01b038116811461197857600080fd5b919050565b6000806040838503121561199057600080fd5b61199983611961565b946020939093013593505050565b6000602082840312156119b957600080fd5b6119c282611961565b9392505050565b602080825282518282018190526000919060409081850190868401855b82811015611a1457815180516001600160a01b031685528601518685015292840192908501906001016119e6565b5091979650505050505050565b602080825282518282018190526000919060409081850190868401855b82811015611a1457815180518552868101516001600160a01b03908116888701528682015187870152606080830151908701526080808301519091169086015260a0808201519086015260c0808201519086015260e0808201519086015261010090810151908501526101209093019290850190600101611a3e565b600080600060608486031215611acf57600080fd5b8335925060208401359150611ae660408501611961565b90509250925092565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b634e487b7160e01b600052601160045260246000fd5b600082821015611b4e57611b4e611b26565b500390565b634e487b7160e01b600052603260045260246000fd5b600060208284031215611b7b57600080fd5b5051919050565b60008219821115611b9557611b95611b26565b500190565b600060208284031215611bac57600080fd5b815180151581146119c257600080fdfea26469706673582212209803f6ae3b37ffb160f796b178f0b43e1f3adce19acbbdec30976d0de543792f64736f6c63430008090033a26469706673582212203539d19152e909370031dae0f40dc1980847bfb7c9638d76301694c5c975c9da64736f6c63430008090033

Deployed ByteCode Sourcemap

106:2861:1:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;509:30;;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;488:15:3;;;470:34;;540:15;;;535:2;520:18;;513:43;592:15;;572:18;;;565:43;;;;420:2;405:18;509:30:1;;;;;;;;951:280;;;;;;:::i;:::-;;:::i;:::-;;380:27;;;;;-1:-1:-1;;;;;380:27:1;;;;;;-1:-1:-1;;;;;1152:32:3;;;1134:51;;1122:2;1107:18;380:27:1;988:203:3;154:58:1;;210:1;154:58;;1706:834;;;;;;:::i;:::-;;:::i;1342:291::-;;;;;;:::i;:::-;;:::i;2643:129::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;414:23::-;;;;;-1:-1:-1;;;414:23:1;;;;;;;;;2893:14:3;;2886:22;2868:41;;2856:2;2841:18;414:23:1;2728:187:3;347:26:1;;;;;;;;;3066:25:3;;;3054:2;3039:18;347:26:1;2920:177:3;454:48:1;;;;;;:::i;:::-;;:::i;2857:105::-;;;:::i;509:30::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;509:30:1;;;;-1:-1:-1;509:30:1;;;;;;:::o;951:280::-;-1:-1:-1;;;;;1017:34:1;;;;;;:64;;-1:-1:-1;1069:12:1;;-1:-1:-1;;;;;1069:12:1;1055:10;:26;1017:64;1009:73;;;;;;1112:12;;;-1:-1:-1;;;;;1135:24:1;;;-1:-1:-1;;;;;;1135:24:1;;;;;;;1181:42;;1112:12;;;1135:24;1112:12;;1181:42;;1093:16;;1181:42;998:233;951:280;:::o;1706:834::-;1851:11;;1823:7;;-1:-1:-1;;;1851:11:1;;;;:20;1843:29;;;;;;-1:-1:-1;;;;;1891:37:1;;;;;;:84;;-1:-1:-1;;;;;;1932:43:1;;;;1891:84;:123;;;;-1:-1:-1;1979:10:1;:35;;1891:123;1883:132;;;;;;2036:14;:16;;;:14;:16;;;:::i;:::-;;;;;;2069:32;2131:13;2146:12;2160:18;2104:75;;;;;:::i;:::-;-1:-1:-1;;;;;488:15:3;;;470:34;;540:15;;;535:2;520:18;;513:43;592:15;;;587:2;572:18;;565:43;420:2;405:18;2104:75:1;;;;;;;;;;;;;;;;;;;;;;;2069:110;;2200:14;2220:51;;;;;;;;2227:9;-1:-1:-1;;;;;2220:51:1;;;;;2238:12;-1:-1:-1;;;;;2220:51:1;;;;;2252:18;-1:-1:-1;;;;;2220:51:1;;;;2200:72;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;2200:72:1;;;;;-1:-1:-1;;;;;2200:72:1;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;2200:72:1;;;;;-1:-1:-1;;;;;2200:72:1;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;2200:72:1;;;;;-1:-1:-1;;;;;2200:72:1;;;;;;;;2283:12;:27;2296:13;-1:-1:-1;;;;;2283:27:1;-1:-1:-1;;;;;2283:27:1;;;;;;;;;;;;2316:93;;;;;;;;2346:9;-1:-1:-1;;;;;2316:93:1;;;;;2366:12;-1:-1:-1;;;;;2316:93:1;;;;;2389:18;-1:-1:-1;;;;;2316:93:1;;;;2283:127;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;2283:127:1;;;;;-1:-1:-1;;;;;2283:127:1;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;2283:127:1;;;;;-1:-1:-1;;;;;2283:127:1;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;2283:127:1;;;;;-1:-1:-1;;;;;2283:127:1;;;;;;;;2475:18;-1:-1:-1;;;;;2428:66:1;2461:12;-1:-1:-1;;;;;2428:66:1;2449:9;-1:-1:-1;;;;;2428:66:1;;;;;;;;;;;2522:9;1706:834;-1:-1:-1;;;;1706:834:1:o;1342:291::-;1422:4;1410:16;;;;;:37;;-1:-1:-1;1430:17:1;;1410:37;1402:46;;;;;;1481:12;;-1:-1:-1;;;;;1481:12:1;1467:10;:26;1459:35;;;;;;1520:11;;;1542:22;;;-1:-1:-1;;;1542:22:1;;;-1:-1:-1;;;;1542:22:1;;;;;;;1586:39;;1520:11;;;;;;;;1586:39;;;;1520:11;;1613;;;;4174:14:3;;4167:22;4149:41;;4233:14;4226:22;4221:2;4206:18;;4199:50;4137:2;4122:18;;3987:268;1586:39:1;;;;;;;;1391:242;1342:291;:::o;2643:129::-;-1:-1:-1;;;;;2742:22:1;;;;;;:12;:22;;;;;;;;2735:29;;;;;;;;;;;;;;;;;2709:15;;2735:29;;2742:22;;2735:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;2735:29:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2643:129;;;:::o;454:48::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;454:48:1;;;;-1:-1:-1;454:48:1;;;;-1:-1:-1;454:48:1;;:::o;2857:105::-;2907:15;2940:14;2933:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;2933:21:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2857:105;:::o;-1:-1:-1:-;;;;;;;;:::o;14:180:3:-;73:6;126:2;114:9;105:7;101:23;97:32;94:52;;;142:1;139;132:12;94:52;-1:-1:-1;165:23:3;;14:180;-1:-1:-1;14:180:3:o;619:173::-;687:20;;-1:-1:-1;;;;;736:31:3;;726:42;;716:70;;782:1;779;772:12;716:70;619:173;;;:::o;797:186::-;856:6;909:2;897:9;888:7;884:23;880:32;877:52;;;925:1;922;915:12;877:52;948:29;967:9;948:29;:::i;:::-;938:39;797:186;-1:-1:-1;;;797:186:3:o;1196:334::-;1273:6;1281;1289;1342:2;1330:9;1321:7;1317:23;1313:32;1310:52;;;1358:1;1355;1348:12;1310:52;1381:29;1400:9;1381:29;:::i;:::-;1371:39;;1429:38;1463:2;1452:9;1448:18;1429:38;:::i;:::-;1419:48;;1486:38;1520:2;1509:9;1505:18;1486:38;:::i;:::-;1476:48;;1196:334;;;;;:::o;1535:273::-;1591:6;1644:2;1632:9;1623:7;1619:23;1615:32;1612:52;;;1660:1;1657;1650:12;1612:52;1699:9;1686:23;1752:5;1745:13;1738:21;1731:5;1728:32;1718:60;;1774:1;1771;1764:12;1813:910;2032:2;2084:21;;;2154:13;;2057:18;;;2176:22;;;2003:4;;2032:2;2217;;2235:18;;;;2276:15;;;2003:4;2319:378;2333:6;2330:1;2327:13;2319:378;;;2392:13;;2476:9;;-1:-1:-1;;;;;2472:18:3;;;2460:31;;2535:11;;;2529:18;2525:27;;2511:12;;;2504:49;2597:11;;;2591:18;2587:27;2573:12;;;2566:49;2644:4;2635:14;;;;2672:15;;;;2445:1;2348:9;2319:378;;;-1:-1:-1;2714:3:3;;1813:910;-1:-1:-1;;;;;;;1813:910:3:o;3102:254::-;3170:6;3178;3231:2;3219:9;3210:7;3206:23;3202:32;3199:52;;;3247:1;3244;3237:12;3199:52;3270:29;3289:9;3270:29;:::i;:::-;3260:39;3346:2;3331:18;;;;3318:32;;-1:-1:-1;;;3102:254:3:o;3361:232::-;3400:3;-1:-1:-1;;3421:17:3;;3418:140;;;3480:10;3475:3;3471:20;3468:1;3461:31;3515:4;3512:1;3505:15;3543:4;3540:1;3533:15;3418:140;-1:-1:-1;3585:1:3;3574:13;;3361:232::o

Swarm Source

ipfs://3539d19152e909370031dae0f40dc1980847bfb7c9638d76301694c5c975c9da
Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.