Goerli Testnet

Contract

0xDDdFf70C77Cffcf97Fb91F7aC4aD0E12E8C14571
Source Code
Transaction Hash
Method
Block
From
To
Value
Deploy Kali DAO97395322023-09-22 12:40:005 days 2 hrs ago1695386400IN
0xDDdFf7...E8C14571
0 ETH0.000853961.50000003
Deploy Kali DAO96612542023-09-08 23:43:3618 days 15 hrs ago1694216616IN
0xDDdFf7...E8C14571
0 ETH0.001112431.5
Deploy Kali DAO96001672023-08-29 8:26:2429 days 6 hrs ago1693297584IN
0xDDdFf7...E8C14571
0 ETH00.00000021
Deploy Kali DAO93099262023-07-08 7:27:2481 days 7 hrs ago1688801244IN
0xDDdFf7...E8C14571
0 ETH0.001263941.50000002
Deploy Kali DAO92657712023-06-30 10:29:4889 days 4 hrs ago1688120988IN
0xDDdFf7...E8C14571
0 ETH0.000999611.50001209
Deploy Kali DAO92166252023-06-21 17:11:1297 days 22 hrs ago1687367472IN
0xDDdFf7...E8C14571
0 ETH0.001337991.50015242
Deploy Kali DAO90846842023-05-29 10:23:24121 days 4 hrs ago1685355804IN
0xDDdFf7...E8C14571
0 ETH0.001177771.76732915
Deploy Kali DAO89313972023-05-02 22:58:24147 days 16 hrs ago1683068304IN
0xDDdFf7...E8C14571
0 ETH0.0445999166.92152094
Deploy Kali DAO89234362023-05-01 13:11:24149 days 2 hrs ago1682946684IN
0xDDdFf7...E8C14571
0 ETH0.0117676517.65719946
Deploy Kali DAO88968252023-04-26 20:54:00153 days 18 hrs ago1682542440IN
0xDDdFf7...E8C14571
0 ETH0.005617718.42854546
Deploy Kali DAO88957402023-04-26 16:21:36153 days 22 hrs ago1682526096IN
0xDDdFf7...E8C14571
0 ETH0.0195316121.89554628
Deploy Kali DAO88366552023-04-15 23:24:00164 days 15 hrs ago1681601040IN
0xDDdFf7...E8C14571
0 ETH0.007039399.05972246
Deploy Kali DAO87396032023-03-29 17:45:24181 days 21 hrs ago1680111924IN
0xDDdFf7...E8C14571
0 ETH0.08330772117.68573099
Deploy Kali DAO87230772023-03-26 20:12:12184 days 19 hrs ago1679861532IN
0xDDdFf7...E8C14571
0 ETH0.0226512131.38269467
Deploy Kali DAO86848082023-03-20 1:11:00191 days 14 hrs ago1679274660IN
0xDDdFf7...E8C14571
0 ETH0.001432611.75357459
Deploy Kali DAO86282092023-03-10 3:26:12201 days 11 hrs ago1678418772IN
0xDDdFf7...E8C14571
0 ETH0.0162995521.97433692
Deploy Kali DAO85664132023-02-27 13:46:00212 days 1 hr ago1677505560IN
0xDDdFf7...E8C14571
0 ETH0.01734726.02814956
Deploy Kali DAO85251422023-02-20 13:52:48219 days 1 hr ago1676901168IN
0xDDdFf7...E8C14571
0 ETH0.0227728327.88110357
Deploy Kali DAO85186732023-02-19 10:53:00220 days 4 hrs ago1676803980IN
0xDDdFf7...E8C14571
0 ETH0.003089164.63535524
Deploy Kali DAO85181952023-02-19 8:52:36220 days 6 hrs ago1676796756IN
0xDDdFf7...E8C14571
0 ETH0.000999561.50000039
Deploy Kali DAO85179132023-02-19 7:40:24220 days 7 hrs ago1676792424IN
0xDDdFf7...E8C14571
0 ETH0.000999761.50000001
Deploy Kali DAO84459992023-02-06 18:51:12232 days 20 hrs ago1675709472IN
0xDDdFf7...E8C14571
0 ETH0.00099971.50000162
Deploy Kali DAO83761492023-01-25 21:50:36244 days 17 hrs ago1674683436IN
0xDDdFf7...E8C14571
0 ETH0.001287281.50000012
Deploy Kali DAO83700482023-01-24 21:03:12245 days 18 hrs ago1674594192IN
0xDDdFf7...E8C14571
0 ETH0.000040841.50000002
Deploy Kali DAO83449352023-01-20 15:00:48250 days 11 mins ago1674226848IN
0xDDdFf7...E8C14571
0 ETH0.0080894911.86099685
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Txn Hash Block From To Value
97395322023-09-22 12:40:005 days 2 hrs ago1695386400
0xDDdFf7...E8C14571
0 ETH
97395322023-09-22 12:40:005 days 2 hrs ago1695386400
0xDDdFf7...E8C14571
 Contract Creation0 ETH
96612542023-09-08 23:43:3618 days 15 hrs ago1694216616
0xDDdFf7...E8C14571
0 ETH
96612542023-09-08 23:43:3618 days 15 hrs ago1694216616
0xDDdFf7...E8C14571
 Contract Creation0 ETH
96001672023-08-29 8:26:2429 days 6 hrs ago1693297584
0xDDdFf7...E8C14571
0 ETH
96001672023-08-29 8:26:2429 days 6 hrs ago1693297584
0xDDdFf7...E8C14571
 Contract Creation0 ETH
93099262023-07-08 7:27:2481 days 7 hrs ago1688801244
0xDDdFf7...E8C14571
0 ETH
93099262023-07-08 7:27:2481 days 7 hrs ago1688801244
0xDDdFf7...E8C14571
 Contract Creation0 ETH
92657712023-06-30 10:29:4889 days 4 hrs ago1688120988
0xDDdFf7...E8C14571
0 ETH
92657712023-06-30 10:29:4889 days 4 hrs ago1688120988
0xDDdFf7...E8C14571
 Contract Creation0 ETH
92166252023-06-21 17:11:1297 days 22 hrs ago1687367472
0xDDdFf7...E8C14571
0 ETH
92166252023-06-21 17:11:1297 days 22 hrs ago1687367472
0xDDdFf7...E8C14571
 Contract Creation0 ETH
90846842023-05-29 10:23:24121 days 4 hrs ago1685355804
0xDDdFf7...E8C14571
0 ETH
90846842023-05-29 10:23:24121 days 4 hrs ago1685355804
0xDDdFf7...E8C14571
 Contract Creation0 ETH
89313972023-05-02 22:58:24147 days 16 hrs ago1683068304
0xDDdFf7...E8C14571
0 ETH
89313972023-05-02 22:58:24147 days 16 hrs ago1683068304
0xDDdFf7...E8C14571
 Contract Creation0 ETH
89234362023-05-01 13:11:24149 days 2 hrs ago1682946684
0xDDdFf7...E8C14571
0 ETH
89234362023-05-01 13:11:24149 days 2 hrs ago1682946684
0xDDdFf7...E8C14571
 Contract Creation0 ETH
88968252023-04-26 20:54:00153 days 18 hrs ago1682542440
0xDDdFf7...E8C14571
0 ETH
88968252023-04-26 20:54:00153 days 18 hrs ago1682542440
0xDDdFf7...E8C14571
 Contract Creation0 ETH
88957402023-04-26 16:21:36153 days 22 hrs ago1682526096
0xDDdFf7...E8C14571
0 ETH
88957402023-04-26 16:21:36153 days 22 hrs ago1682526096
0xDDdFf7...E8C14571
 Contract Creation0 ETH
88366552023-04-15 23:24:00164 days 15 hrs ago1681601040
0xDDdFf7...E8C14571
0 ETH
88366552023-04-15 23:24:00164 days 15 hrs ago1681601040
0xDDdFf7...E8C14571
 Contract Creation0 ETH
87396032023-03-29 17:45:24181 days 21 hrs ago1680111924
0xDDdFf7...E8C14571
0 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
KaliDAOfactory

Compiler Version
v0.8.14+commit.80d49f37

Optimization Enabled:
Yes with 11111 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 1 : KaliDAOfactory.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity >=0.8.4;

/// @notice Modern and gas-optimized ERC-20 + EIP-2612 implementation with COMP-style governance and pausing.
/// @author Modified from Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/erc20/ERC20.sol)
/// License-Identifier: AGPL-3.0-only
abstract contract KaliDAOtoken {
    /*///////////////////////////////////////////////////////////////
                            EVENTS
    //////////////////////////////////////////////////////////////*/

    event Transfer(address indexed from, address indexed to, uint256 amount);

    event Approval(address indexed owner, address indexed spender, uint256 amount);

    event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);

    event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);

    event PauseFlipped(bool paused);

    /*///////////////////////////////////////////////////////////////
                            ERRORS
    //////////////////////////////////////////////////////////////*/

    error NoArrayParity();

    error Paused();

    error SignatureExpired();

    error NullAddress();

    error InvalidNonce();

    error NotDetermined();

    error InvalidSignature();

    error Uint32max();

    error Uint96max();

    /*///////////////////////////////////////////////////////////////
                            METADATA STORAGE
    //////////////////////////////////////////////////////////////*/

    string public name;

    string public symbol;

    uint8 public constant decimals = 18;

    /*///////////////////////////////////////////////////////////////
                            ERC-20 STORAGE
    //////////////////////////////////////////////////////////////*/

    uint256 public totalSupply;

    mapping(address => uint256) public balanceOf;

    mapping(address => mapping(address => uint256)) public allowance;

    /*///////////////////////////////////////////////////////////////
                            EIP-2612 STORAGE
    //////////////////////////////////////////////////////////////*/

    bytes32 public constant PERMIT_TYPEHASH =
        keccak256('Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)');

    uint256 internal INITIAL_CHAIN_ID;

    bytes32 internal INITIAL_DOMAIN_SEPARATOR;

    mapping(address => uint256) public nonces;

    /*///////////////////////////////////////////////////////////////
                            DAO STORAGE
    //////////////////////////////////////////////////////////////*/

    bool public paused;

    bytes32 public constant DELEGATION_TYPEHASH = 
        keccak256('Delegation(address delegatee,uint256 nonce,uint256 deadline)');

    mapping(address => address) internal _delegates;

    mapping(address => mapping(uint256 => Checkpoint)) public checkpoints;

    mapping(address => uint256) public numCheckpoints;

    struct Checkpoint {
        uint32 fromTimestamp;
        uint96 votes;
    }

    /*///////////////////////////////////////////////////////////////
                            CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    function _init(
        string memory name_,
        string memory symbol_,
        bool paused_,
        address[] memory voters_,
        uint256[] memory shares_
    ) internal virtual {
        if (voters_.length != shares_.length) revert NoArrayParity();

        name = name_;
        
        symbol = symbol_;
        
        paused = paused_;

        INITIAL_CHAIN_ID = block.chainid;
        
        INITIAL_DOMAIN_SEPARATOR = _computeDomainSeparator();
        
        // cannot realistically overflow on human timescales
        unchecked {
            for (uint256 i; i < voters_.length; i++) {
                _mint(voters_[i], shares_[i]);
            }
        }
    }

    /*///////////////////////////////////////////////////////////////
                            ERC-20 LOGIC
    //////////////////////////////////////////////////////////////*/

    function approve(address spender, uint256 amount) public payable virtual returns (bool) {
        allowance[msg.sender][spender] = amount;

        emit Approval(msg.sender, spender, amount);

        return true;
    }

    function transfer(address to, uint256 amount) public payable notPaused virtual returns (bool) {
        balanceOf[msg.sender] -= amount;

        // cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value
        unchecked {
            balanceOf[to] += amount;
        }
        
        _moveDelegates(delegates(msg.sender), delegates(to), amount);

        emit Transfer(msg.sender, to, amount);

        return true;
    }

    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public payable notPaused virtual returns (bool) {
        if (allowance[from][msg.sender] != type(uint256).max) 
            allowance[from][msg.sender] -= amount;

        balanceOf[from] -= amount;

        // cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value
        unchecked {
            balanceOf[to] += amount;
        }
        
        _moveDelegates(delegates(from), delegates(to), amount);

        emit Transfer(from, to, amount);

        return true;
    }

    /*///////////////////////////////////////////////////////////////
                            EIP-2612 LOGIC
    //////////////////////////////////////////////////////////////*/
    
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public payable virtual {
        if (block.timestamp > deadline) revert SignatureExpired();

        // cannot realistically overflow on human timescales
        unchecked {
            bytes32 digest = keccak256(
                abi.encodePacked(
                    '\x19\x01',
                    DOMAIN_SEPARATOR(),
                    keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline))
                )
            );

            address recoveredAddress = ecrecover(digest, v, r, s);

            if (recoveredAddress == address(0) || recoveredAddress != owner) revert InvalidSignature();

            allowance[recoveredAddress][spender] = value;
        }

        emit Approval(owner, spender, value);
    }

    function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
        return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : _computeDomainSeparator();
    }

    function _computeDomainSeparator() internal view virtual returns (bytes32) {
        return 
            keccak256(
                abi.encode(
                    keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'),
                    keccak256(bytes(name)),
                    keccak256('1'),
                    block.chainid,
                    address(this)
                )
            );
    }

    /*///////////////////////////////////////////////////////////////
                            DAO LOGIC
    //////////////////////////////////////////////////////////////*/

    modifier notPaused() {
        if (paused) revert Paused();

        _;
    }
    
    function delegates(address delegator) public view virtual returns (address) {
        address current = _delegates[delegator];
        
        return current == address(0) ? delegator : current;
    }

    function getCurrentVotes(address account) public view virtual returns (uint256) {
        // this is safe from underflow because decrement only occurs if `nCheckpoints` is positive
        unchecked {
            uint256 nCheckpoints = numCheckpoints[account];

            return nCheckpoints != 0 ? checkpoints[account][nCheckpoints - 1].votes : 0;
        }
    }

    function delegate(address delegatee) public payable virtual {
        _delegate(msg.sender, delegatee);
    }

    function delegateBySig(
        address delegatee, 
        uint256 nonce, 
        uint256 deadline, 
        uint8 v, 
        bytes32 r, 
        bytes32 s
    ) public payable virtual {
        if (block.timestamp > deadline) revert SignatureExpired();

        bytes32 structHash = keccak256(abi.encode(DELEGATION_TYPEHASH, delegatee, nonce, deadline));

        bytes32 digest = keccak256(abi.encodePacked('\x19\x01', DOMAIN_SEPARATOR(), structHash));

        address signatory = ecrecover(digest, v, r, s);

        if (signatory == address(0)) revert NullAddress();
        
        // cannot realistically overflow on human timescales
        unchecked {
            if (nonce != nonces[signatory]++) revert InvalidNonce();
        }

        _delegate(signatory, delegatee);
    }

    function getPriorVotes(address account, uint256 timestamp) public view virtual returns (uint96) {
        if (block.timestamp <= timestamp) revert NotDetermined();

        uint256 nCheckpoints = numCheckpoints[account];

        if (nCheckpoints == 0) return 0;
        
        // this is safe from underflow because decrement only occurs if `nCheckpoints` is positive
        unchecked {
            if (checkpoints[account][nCheckpoints - 1].fromTimestamp <= timestamp)
                return checkpoints[account][nCheckpoints - 1].votes;

            if (checkpoints[account][0].fromTimestamp > timestamp) return 0;

            uint256 lower;
            
            // this is safe from underflow because decrement only occurs if `nCheckpoints` is positive
            uint256 upper = nCheckpoints - 1;

            while (upper > lower) {
                // this is safe from underflow because `upper` ceiling is provided
                uint256 center = upper - (upper - lower) / 2;

                Checkpoint memory cp = checkpoints[account][center];

                if (cp.fromTimestamp == timestamp) {
                    return cp.votes;
                } else if (cp.fromTimestamp < timestamp) {
                    lower = center;
                } else {
                    upper = center - 1;
                }
            }

        return checkpoints[account][lower].votes;

        }
    }

    function _delegate(address delegator, address delegatee) internal virtual {
        address currentDelegate = delegates(delegator);

        _delegates[delegator] = delegatee;

        _moveDelegates(currentDelegate, delegatee, balanceOf[delegator]);

        emit DelegateChanged(delegator, currentDelegate, delegatee);
    }

    function _moveDelegates(
        address srcRep, 
        address dstRep, 
        uint256 amount
    ) internal virtual {
        if (srcRep != dstRep && amount != 0) 
            if (srcRep != address(0)) {
                uint256 srcRepNum = numCheckpoints[srcRep];
                
                uint256 srcRepOld = srcRepNum != 0 ? checkpoints[srcRep][srcRepNum - 1].votes : 0;

                uint256 srcRepNew = srcRepOld - amount;

                _writeCheckpoint(srcRep, srcRepNum, srcRepOld, srcRepNew);
            }
            
            if (dstRep != address(0)) {
                uint256 dstRepNum = numCheckpoints[dstRep];

                uint256 dstRepOld = dstRepNum != 0 ? checkpoints[dstRep][dstRepNum - 1].votes : 0;

                uint256 dstRepNew = dstRepOld + amount;

                _writeCheckpoint(dstRep, dstRepNum, dstRepOld, dstRepNew);
            }
    }

    function _writeCheckpoint(
        address delegatee, 
        uint256 nCheckpoints, 
        uint256 oldVotes, 
        uint256 newVotes
    ) internal virtual {
        unchecked {
            // this is safe from underflow because decrement only occurs if `nCheckpoints` is positive
            if (nCheckpoints != 0 && checkpoints[delegatee][nCheckpoints - 1].fromTimestamp == block.timestamp) {
                checkpoints[delegatee][nCheckpoints - 1].votes = _safeCastTo96(newVotes);
            } else {
                checkpoints[delegatee][nCheckpoints] = Checkpoint(_safeCastTo32(block.timestamp), _safeCastTo96(newVotes));
                
                // cannot realistically overflow on human timescales
                numCheckpoints[delegatee] = nCheckpoints + 1;
            }
        }

        emit DelegateVotesChanged(delegatee, oldVotes, newVotes);
    }

    /*///////////////////////////////////////////////////////////////
                            MINT/BURN LOGIC
    //////////////////////////////////////////////////////////////*/

    function _mint(address to, uint256 amount) internal virtual {
        totalSupply += amount;

        // cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value
        unchecked {
            balanceOf[to] += amount;
        }

        _moveDelegates(address(0), delegates(to), amount);

        emit Transfer(address(0), to, amount);
    }

    function _burn(address from, uint256 amount) internal virtual {
        balanceOf[from] -= amount;

        // cannot underflow because a user's balance
        // will never be larger than the total supply
        unchecked {
            totalSupply -= amount;
        }

        _moveDelegates(delegates(from), address(0), amount);

        emit Transfer(from, address(0), amount);
    }
    
    function burn(uint256 amount) public payable virtual {
        _burn(msg.sender, amount);
    }

    function burnFrom(address from, uint256 amount) public payable virtual {
        if (allowance[from][msg.sender] != type(uint256).max) 
            allowance[from][msg.sender] -= amount;

        _burn(from, amount);
    }

    /*///////////////////////////////////////////////////////////////
                            PAUSE LOGIC
    //////////////////////////////////////////////////////////////*/

    function _flipPause() internal virtual {
        paused = !paused;

        emit PauseFlipped(paused);
    }
    
    /*///////////////////////////////////////////////////////////////
                            SAFECAST LOGIC
    //////////////////////////////////////////////////////////////*/
    
    function _safeCastTo32(uint256 x) internal pure virtual returns (uint32) {
        if (x > type(uint32).max) revert Uint32max();

        return uint32(x);
    }
    
    function _safeCastTo96(uint256 x) internal pure virtual returns (uint96) {
        if (x > type(uint96).max) revert Uint96max();

        return uint96(x);
    }
}

/// @notice Helper utility that enables calling multiple local methods in a single call.
/// @author Modified from Uniswap (https://github.com/Uniswap/v3-periphery/blob/main/contracts/base/Multicall.sol)
abstract contract Multicall {
    function multicall(bytes[] calldata data) public payable virtual returns (bytes[] memory results) {
        results = new bytes[](data.length);
        
        // cannot realistically overflow on human timescales
        unchecked {
            for (uint256 i = 0; i < data.length; i++) {
                (bool success, bytes memory result) = address(this).delegatecall(data[i]);

                if (!success) {
                    if (result.length < 68) revert();
                    
                    assembly {
                        result := add(result, 0x04)
                    }
                    
                    revert(abi.decode(result, (string)));
                }
                results[i] = result;
            }
        }
    }
}

/// @notice Helper utility for NFT 'safe' transfers.
abstract contract NFThelper {
    function onERC721Received(
        address,
        address,
        uint256,
        bytes calldata
    ) external pure returns (bytes4 sig) {
        sig = 0x150b7a02; // 'onERC721Received(address,address,uint256,bytes)'
    }

    function onERC1155Received(
        address,
        address,
        uint256,
        uint256,
        bytes calldata
    ) external pure returns (bytes4 sig) {
        sig = 0xf23a6e61; // 'onERC1155Received(address,address,uint256,uint256,bytes)'
    }
    
    function onERC1155BatchReceived(
        address,
        address,
        uint256[] calldata,
        uint256[] calldata,
        bytes calldata
    ) external pure returns (bytes4 sig) {
        sig = 0xbc197c81; // 'onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)'
    }
}

/// @notice Gas-optimized reentrancy protection.
/// @author Modified from OpenZeppelin 
/// (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/security/ReentrancyGuard.sol)
/// License-Identifier: MIT
abstract contract ReentrancyGuard {
    error Reentrancy();

    uint256 private constant NOT_ENTERED = 1;

    uint256 private constant ENTERED = 2;

    uint256 private status = NOT_ENTERED;

    modifier nonReentrant() {
        if (status == ENTERED) revert Reentrancy();

        status = ENTERED;

        _;

        status = NOT_ENTERED;
    }
}

/// @notice Kali DAO membership extension interface.
interface IKaliDAOextension {
    function setExtension(bytes calldata extensionData) external;

    function callExtension(
        address account, 
        uint256 amount, 
        bytes calldata extensionData
    ) external payable returns (bool mint, uint256 amountOut);
}

/// @notice Simple gas-optimized Kali DAO core module.
contract KaliDAO is KaliDAOtoken, Multicall, NFThelper, ReentrancyGuard {
    /*///////////////////////////////////////////////////////////////
                            EVENTS
    //////////////////////////////////////////////////////////////*/

    event NewProposal(
        address indexed proposer, 
        uint256 indexed proposal, 
        ProposalType indexed proposalType, 
        string description, 
        address[] accounts, 
        uint256[] amounts, 
        bytes[] payloads
    );

    event ProposalCancelled(address indexed proposer, uint256 indexed proposal);

    event ProposalSponsored(address indexed sponsor, uint256 indexed proposal);
    
    event VoteCast(address indexed voter, uint256 indexed proposal, bool indexed approve);

    event ProposalProcessed(uint256 indexed proposal, bool indexed didProposalPass);

    /*///////////////////////////////////////////////////////////////
                            ERRORS
    //////////////////////////////////////////////////////////////*/

    error Initialized();

    error PeriodBounds();

    error QuorumMax();

    error SupermajorityBounds();

    error InitCallFail();

    error TypeBounds();

    error NotProposer();

    error Sponsored();

    error NotMember();

    error NotCurrentProposal();

    error AlreadyVoted();

    error NotVoteable();

    error VotingNotEnded();

    error PrevNotProcessed();

    error NotExtension();

    /*///////////////////////////////////////////////////////////////
                            DAO STORAGE
    //////////////////////////////////////////////////////////////*/

    string public docs;

    uint256 private currentSponsoredProposal;
    
    uint256 public proposalCount;

    uint32 public votingPeriod;

    uint32 public gracePeriod;

    uint32 public quorum; // 1-100

    uint32 public supermajority; // 1-100
    
    bytes32 public constant VOTE_HASH = 
        keccak256('SignVote(address signer,uint256 proposal,bool approve)');
    
    mapping(address => bool) public extensions;

    mapping(uint256 => Proposal) public proposals;

    mapping(uint256 => ProposalState) public proposalStates;

    mapping(ProposalType => VoteType) public proposalVoteTypes;
    
    mapping(uint256 => mapping(address => bool)) public voted;

    mapping(address => uint256) public lastYesVote;

    enum ProposalType {
        MINT, // add membership
        BURN, // revoke membership
        CALL, // call contracts
        VPERIOD, // set `votingPeriod`
        GPERIOD, // set `gracePeriod`
        QUORUM, // set `quorum`
        SUPERMAJORITY, // set `supermajority`
        TYPE, // set `VoteType` to `ProposalType`
        PAUSE, // flip membership transferability
        EXTENSION, // flip `extensions` whitelisting
        ESCAPE, // delete pending proposal in case of revert
        DOCS // amend org docs
    }

    enum VoteType {
        SIMPLE_MAJORITY,
        SIMPLE_MAJORITY_QUORUM_REQUIRED,
        SUPERMAJORITY,
        SUPERMAJORITY_QUORUM_REQUIRED
    }

    struct Proposal {
        ProposalType proposalType;
        string description;
        address[] accounts; // member(s) being added/kicked; account(s) receiving payload
        uint256[] amounts; // value(s) to be minted/burned/spent; gov setting [0]
        bytes[] payloads; // data for CALL proposals
        uint256 prevProposal;
        uint96 yesVotes;
        uint96 noVotes;
        uint32 creationTime;
        address proposer;
    }

    struct ProposalState {
        bool passed;
        bool processed;
    }

    /*///////////////////////////////////////////////////////////////
                            CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    function init(
        string memory name_,
        string memory symbol_,
        string memory docs_,
        bool paused_,
        address[] memory extensions_,
        bytes[] memory extensionsData_,
        address[] calldata voters_,
        uint256[] calldata shares_,
        uint32[16] memory govSettings_
    ) public payable nonReentrant virtual {
        if (extensions_.length != extensionsData_.length) revert NoArrayParity();

        if (votingPeriod != 0) revert Initialized();

        if (govSettings_[0] == 0 || govSettings_[0] > 365 days) revert PeriodBounds();

        if (govSettings_[1] > 365 days) revert PeriodBounds();

        if (govSettings_[2] > 100) revert QuorumMax();

        if (govSettings_[3] <= 51 || govSettings_[3] > 100) revert SupermajorityBounds();

        KaliDAOtoken._init(name_, symbol_, paused_, voters_, shares_);

        if (extensions_.length != 0) {
            // cannot realistically overflow on human timescales
            unchecked {
                for (uint256 i; i < extensions_.length; i++) {
                    extensions[extensions_[i]] = true;

                    if (extensionsData_[i].length > 3) {
                        (bool success, ) = extensions_[i].call(extensionsData_[i]);

                        if (!success) revert InitCallFail();
                    }
                }
            }
        }

        docs = docs_;
        
        votingPeriod = govSettings_[0];

        gracePeriod = govSettings_[1];
        
        quorum = govSettings_[2];
        
        supermajority = govSettings_[3];

        // set initial vote types
        proposalVoteTypes[ProposalType.MINT] = VoteType(govSettings_[4]);

        proposalVoteTypes[ProposalType.BURN] = VoteType(govSettings_[5]);

        proposalVoteTypes[ProposalType.CALL] = VoteType(govSettings_[6]);

        proposalVoteTypes[ProposalType.VPERIOD] = VoteType(govSettings_[7]);

        proposalVoteTypes[ProposalType.GPERIOD] = VoteType(govSettings_[8]);
        
        proposalVoteTypes[ProposalType.QUORUM] = VoteType(govSettings_[9]);
        
        proposalVoteTypes[ProposalType.SUPERMAJORITY] = VoteType(govSettings_[10]);

        proposalVoteTypes[ProposalType.TYPE] = VoteType(govSettings_[11]);
        
        proposalVoteTypes[ProposalType.PAUSE] = VoteType(govSettings_[12]);
        
        proposalVoteTypes[ProposalType.EXTENSION] = VoteType(govSettings_[13]);

        proposalVoteTypes[ProposalType.ESCAPE] = VoteType(govSettings_[14]);

        proposalVoteTypes[ProposalType.DOCS] = VoteType(govSettings_[15]);
    }

    /*///////////////////////////////////////////////////////////////
                            PROPOSAL LOGIC
    //////////////////////////////////////////////////////////////*/

    function getProposalArrays(uint256 proposal) public view virtual returns (
        address[] memory accounts, 
        uint256[] memory amounts, 
        bytes[] memory payloads
    ) {
        Proposal storage prop = proposals[proposal];
        
        (accounts, amounts, payloads) = (prop.accounts, prop.amounts, prop.payloads);
    }

    function propose(
        ProposalType proposalType,
        string calldata description,
        address[] calldata accounts,
        uint256[] calldata amounts,
        bytes[] calldata payloads
    ) public payable nonReentrant virtual returns (uint256 proposal) {
        if (accounts.length != amounts.length || amounts.length != payloads.length) revert NoArrayParity();
        
        if (proposalType == ProposalType.VPERIOD) if (amounts[0] == 0 || amounts[0] > 365 days) revert PeriodBounds();

        if (proposalType == ProposalType.GPERIOD) if (amounts[0] > 365 days) revert PeriodBounds();
        
        if (proposalType == ProposalType.QUORUM) if (amounts[0] > 100) revert QuorumMax();
        
        if (proposalType == ProposalType.SUPERMAJORITY) if (amounts[0] <= 51 || amounts[0] > 100) revert SupermajorityBounds();

        if (proposalType == ProposalType.TYPE) if (amounts[0] > 11 || amounts[1] > 3 || amounts.length != 2) revert TypeBounds();

        bool selfSponsor;

        // if member or extension is making proposal, include sponsorship
        if (balanceOf[msg.sender] != 0 || extensions[msg.sender]) selfSponsor = true;

        // cannot realistically overflow on human timescales
        unchecked {
            proposalCount++;
        }

        proposal = proposalCount;

        proposals[proposal] = Proposal({
            proposalType: proposalType,
            description: description,
            accounts: accounts,
            amounts: amounts,
            payloads: payloads,
            prevProposal: selfSponsor ? currentSponsoredProposal : 0,
            yesVotes: 0,
            noVotes: 0,
            creationTime: selfSponsor ? _safeCastTo32(block.timestamp) : 0,
            proposer: msg.sender
        });

        if (selfSponsor) currentSponsoredProposal = proposal;

        emit NewProposal(msg.sender, proposal, proposalType, description, accounts, amounts, payloads);
    }

    function cancelProposal(uint256 proposal) public payable nonReentrant virtual {
        Proposal storage prop = proposals[proposal];

        if (msg.sender != prop.proposer) revert NotProposer();

        if (prop.creationTime != 0) revert Sponsored();

        delete proposals[proposal];

        emit ProposalCancelled(msg.sender, proposal);
    }

    function sponsorProposal(uint256 proposal) public payable nonReentrant virtual {
        Proposal storage prop = proposals[proposal];

        if (balanceOf[msg.sender] == 0) revert NotMember();

        if (prop.proposer == address(0)) revert NotCurrentProposal();

        if (prop.creationTime != 0) revert Sponsored();

        prop.prevProposal = currentSponsoredProposal;

        currentSponsoredProposal = proposal;

        prop.creationTime = _safeCastTo32(block.timestamp);

        emit ProposalSponsored(msg.sender, proposal);
    } 

    function vote(uint256 proposal, bool approve) public payable nonReentrant virtual {
        _vote(msg.sender, proposal, approve);
    }
    
    function voteBySig(
        address signer, 
        uint256 proposal, 
        bool approve, 
        uint8 v, 
        bytes32 r, 
        bytes32 s
    ) public payable nonReentrant virtual {
        bytes32 digest =
            keccak256(
                abi.encodePacked(
                    '\x19\x01',
                    DOMAIN_SEPARATOR(),
                    keccak256(
                        abi.encode(
                            VOTE_HASH,
                            signer,
                            proposal,
                            approve
                        )
                    )
                )
            );
            
        address recoveredAddress = ecrecover(digest, v, r, s);

        if (recoveredAddress == address(0) || recoveredAddress != signer) revert InvalidSignature();
        
        _vote(signer, proposal, approve);
    }
    
    function _vote(
        address signer, 
        uint256 proposal, 
        bool approve
    ) internal virtual {
        Proposal storage prop = proposals[proposal];

        if (voted[proposal][signer]) revert AlreadyVoted();
        
        // this is safe from overflow because `votingPeriod` is capped so it will not combine
        // with unix time to exceed the max uint256 value
        unchecked {
            if (block.timestamp > prop.creationTime + votingPeriod) revert NotVoteable();
        }

        uint96 weight = getPriorVotes(signer, prop.creationTime);
        
        // this is safe from overflow because `yesVotes` and `noVotes` are capped by `totalSupply`
        // which is checked for overflow in `KaliDAOtoken` contract
        unchecked { 
            if (approve) {
                prop.yesVotes += weight;

                lastYesVote[signer] = proposal;
            } else {
                prop.noVotes += weight;
            }
        }
        
        voted[proposal][signer] = true;
        
        emit VoteCast(signer, proposal, approve);
    }

    function processProposal(uint256 proposal) public payable nonReentrant virtual returns (
        bool didProposalPass, bytes[] memory results
    ) {
        Proposal storage prop = proposals[proposal];

        VoteType voteType = proposalVoteTypes[prop.proposalType];

        if (prop.creationTime == 0) revert NotCurrentProposal();
        
        // this is safe from overflow because `votingPeriod` and `gracePeriod` are capped so they will not combine
        // with unix time to exceed the max uint256 value
        unchecked {
            if (block.timestamp <= prop.creationTime + votingPeriod + gracePeriod) revert VotingNotEnded();
        }

        // skip previous proposal processing requirement in case of escape hatch
        if (prop.proposalType != ProposalType.ESCAPE) 
            if (proposals[prop.prevProposal].creationTime != 0) revert PrevNotProcessed();

        didProposalPass = _countVotes(voteType, prop.yesVotes, prop.noVotes);
        
        if (didProposalPass) {
            // cannot realistically overflow on human timescales
            unchecked {
                if (prop.proposalType == ProposalType.MINT) 
                    for (uint256 i; i < prop.accounts.length; i++) {
                        _mint(prop.accounts[i], prop.amounts[i]);
                    }
                    
                if (prop.proposalType == ProposalType.BURN) 
                    for (uint256 i; i < prop.accounts.length; i++) {
                        _burn(prop.accounts[i], prop.amounts[i]);
                    }
                    
                if (prop.proposalType == ProposalType.CALL) 
                    for (uint256 i; i < prop.accounts.length; i++) {
                        results = new bytes[](prop.accounts.length);
                        
                        (, bytes memory result) = prop.accounts[i].call{value: prop.amounts[i]}
                            (prop.payloads[i]);
                        
                        results[i] = result;
                    }
                    
                // governance settings
                if (prop.proposalType == ProposalType.VPERIOD) 
                    if (prop.amounts[0] != 0) votingPeriod = uint32(prop.amounts[0]);
                
                if (prop.proposalType == ProposalType.GPERIOD) 
                    if (prop.amounts[0] != 0) gracePeriod = uint32(prop.amounts[0]);
                
                if (prop.proposalType == ProposalType.QUORUM) 
                    if (prop.amounts[0] != 0) quorum = uint32(prop.amounts[0]);
                
                if (prop.proposalType == ProposalType.SUPERMAJORITY) 
                    if (prop.amounts[0] != 0) supermajority = uint32(prop.amounts[0]);
                
                if (prop.proposalType == ProposalType.TYPE) 
                    proposalVoteTypes[ProposalType(prop.amounts[0])] = VoteType(prop.amounts[1]);
                
                if (prop.proposalType == ProposalType.PAUSE) 
                    _flipPause();
                
                if (prop.proposalType == ProposalType.EXTENSION) 
                    for (uint256 i; i < prop.accounts.length; i++) {
                        if (prop.amounts[i] != 0) 
                            extensions[prop.accounts[i]] = !extensions[prop.accounts[i]];
                    
                        if (prop.payloads[i].length > 3) IKaliDAOextension(prop.accounts[i])
                            .setExtension(prop.payloads[i]);
                    }
                
                if (prop.proposalType == ProposalType.ESCAPE)
                    delete proposals[prop.amounts[0]];

                if (prop.proposalType == ProposalType.DOCS)
                    docs = prop.description;
                
                proposalStates[proposal].passed = true;
            }
        }

        delete proposals[proposal];

        proposalStates[proposal].processed = true;

        emit ProposalProcessed(proposal, didProposalPass);
    }

    function _countVotes(
        VoteType voteType,
        uint256 yesVotes,
        uint256 noVotes
    ) internal view virtual returns (bool didProposalPass) {
        // fail proposal if no participation
        if (yesVotes == 0 && noVotes == 0) return false;

        // rule out any failed quorums
        if (voteType == VoteType.SIMPLE_MAJORITY_QUORUM_REQUIRED || voteType == VoteType.SUPERMAJORITY_QUORUM_REQUIRED) {
            uint256 minVotes = (totalSupply * quorum) / 100;
            
            // this is safe from overflow because `yesVotes` and `noVotes` 
            // supply are checked in `KaliDAOtoken` contract
            unchecked {
                uint256 votes = yesVotes + noVotes;

                if (votes < minVotes) return false;
            }
        }
        
        // simple majority check
        if (voteType == VoteType.SIMPLE_MAJORITY || voteType == VoteType.SIMPLE_MAJORITY_QUORUM_REQUIRED) {
            if (yesVotes > noVotes) return true;
        // supermajority check
        } else {
            // example: 7 yes, 2 no, supermajority = 66
            // ((7+2) * 66) / 100 = 5.94; 7 yes will pass
            uint256 minYes = ((yesVotes + noVotes) * supermajority) / 100;

            if (yesVotes >= minYes) return true;
        }
    }
    
    /*///////////////////////////////////////////////////////////////
                            EXTENSIONS 
    //////////////////////////////////////////////////////////////*/

    receive() external payable virtual {}

    modifier onlyExtension {
        if (!extensions[msg.sender]) revert NotExtension();

        _;
    }

    function callExtension(
        address extension, 
        uint256 amount, 
        bytes calldata extensionData
    ) public payable nonReentrant virtual returns (bool mint, uint256 amountOut) {
        if (!extensions[extension]) revert NotExtension();
        
        (mint, amountOut) = IKaliDAOextension(extension).callExtension{value: msg.value}
            (msg.sender, amount, extensionData);
        
        if (mint) {
            if (amountOut != 0) _mint(msg.sender, amountOut); 
        } else {
            if (amountOut != 0) _burn(msg.sender, amount);
        }
    }

    function mintShares(address to, uint256 amount) public payable onlyExtension virtual {
        _mint(to, amount);
    }

    function burnShares(address from, uint256 amount) public payable onlyExtension virtual {
        _burn(from, amount);
    }
}

/// @notice Ricardian LLC formation interface.
interface IRicardianLLC {
    function mintLLC(address to) external payable;
}

/// @notice Factory to deploy Kali DAO.
contract KaliDAOfactory is Multicall {
    event DAOdeployed(
        KaliDAO indexed kaliDAO, 
        string name, 
        string symbol, 
        string docs, 
        bool paused, 
        address[] extensions, 
        bytes[] extensionsData,
        address[] voters,
        uint256[] shares,
        uint32[16] govSettings
    );

    error NullDeploy();

    address payable private immutable kaliMaster;

    IRicardianLLC private immutable ricardianLLC;

    constructor(address payable kaliMaster_, IRicardianLLC ricardianLLC_) {
        kaliMaster = kaliMaster_;

        ricardianLLC = ricardianLLC_;
    }
    
    function deployKaliDAO(
        string memory name_,
        string memory symbol_,
        string memory docs_,
        bool paused_,
        address[] memory extensions_,
        bytes[] memory extensionsData_,
        address[] calldata voters_,
        uint256[] calldata shares_,
        uint32[16] memory govSettings_
    ) public payable virtual returns (KaliDAO kaliDAO) {
        kaliDAO = KaliDAO(_cloneAsMinimalProxy(kaliMaster, name_));
        
        kaliDAO.init(
            name_, 
            symbol_, 
            docs_,
            paused_, 
            extensions_,
            extensionsData_,
            voters_, 
            shares_,  
            govSettings_
        );

        bytes memory docs = bytes(docs_);

        if (docs.length == 0) {
            ricardianLLC.mintLLC{value: msg.value}(address(kaliDAO));
        }

        emit DAOdeployed(kaliDAO, name_, symbol_, docs_, paused_, extensions_, extensionsData_, voters_, shares_, govSettings_);
    }

    /// @dev modified from Aelin (https://github.com/AelinXYZ/aelin/blob/main/contracts/MinimalProxyFactory.sol)
    function _cloneAsMinimalProxy(address payable base, string memory name_) internal virtual returns (address payable clone) {
        bytes memory createData = abi.encodePacked(
            // constructor
            bytes10(0x3d602d80600a3d3981f3),
            // proxy code
            bytes10(0x363d3d373d3d3d363d73),
            base,
            bytes15(0x5af43d82803e903d91602b57fd5bf3)
        );

        bytes32 salt = keccak256(bytes(name_));

        assembly {
            clone := create2(
                0, // no value
                add(createData, 0x20), // data
                mload(createData),
                salt
            )
        }
        // if CREATE2 fails for some reason, address(0) is returned
        if (clone == address(0)) revert NullDeploy();
    }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 11111
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract ABI

[{"inputs":[{"internalType":"address payable","name":"kaliMaster_","type":"address"},{"internalType":"contract IRicardianLLC","name":"ricardianLLC_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"NullDeploy","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract KaliDAO","name":"kaliDAO","type":"address"},{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"string","name":"symbol","type":"string"},{"indexed":false,"internalType":"string","name":"docs","type":"string"},{"indexed":false,"internalType":"bool","name":"paused","type":"bool"},{"indexed":false,"internalType":"address[]","name":"extensions","type":"address[]"},{"indexed":false,"internalType":"bytes[]","name":"extensionsData","type":"bytes[]"},{"indexed":false,"internalType":"address[]","name":"voters","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"shares","type":"uint256[]"},{"indexed":false,"internalType":"uint32[16]","name":"govSettings","type":"uint32[16]"}],"name":"DAOdeployed","type":"event"},{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"string","name":"docs_","type":"string"},{"internalType":"bool","name":"paused_","type":"bool"},{"internalType":"address[]","name":"extensions_","type":"address[]"},{"internalType":"bytes[]","name":"extensionsData_","type":"bytes[]"},{"internalType":"address[]","name":"voters_","type":"address[]"},{"internalType":"uint256[]","name":"shares_","type":"uint256[]"},{"internalType":"uint32[16]","name":"govSettings_","type":"uint32[16]"}],"name":"deployKaliDAO","outputs":[{"internalType":"contract KaliDAO","name":"kaliDAO","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"multicall","outputs":[{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"stateMutability":"payable","type":"function"}]

60c060405234801561001057600080fd5b50604051610eb0380380610eb083398101604081905261002f9161005e565b6001600160a01b039182166080521660a052610098565b6001600160a01b038116811461005b57600080fd5b50565b6000806040838503121561007157600080fd5b825161007c81610046565b602084015190925061008d81610046565b809150509250929050565b60805160a051610df46100bc60003960006101a30152600060920152610df46000f3fe6080604052600436106100295760003560e01c806309ef16021461002e578063ac9650d81461006b575b600080fd5b61004161003c366004610860565b61008b565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61007e6100793660046109af565b610274565b6040516100629190610ac0565b60006100b77f00000000000000000000000000000000000000000000000000000000000000008d6103e4565b6040517f97b55f8100000000000000000000000000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff8216906397b55f8190610120908f908f908f908f908f908f908f908f908f908f908f90600401610b9f565b600060405180830381600087803b15801561013a57600080fd5b505af115801561014e573d6000803e3d6000fd5b50508b518c92506000039050610202576040517f6f0a5e7100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301527f00000000000000000000000000000000000000000000000000000000000000001690636f0a5e719034906024016000604051808303818588803b1580156101e857600080fd5b505af11580156101fc573d6000803e3d6000fd5b50505050505b8173ffffffffffffffffffffffffffffffffffffffff167f0712ea2ebe8ee974f78171c5f86c898cc0e2858fb69ed676083f8c60ee84ab128e8e8e8e8e8e8e8e8e8e8e60405161025c9b9a99989796959493929190610b9f565b60405180910390a2509b9a5050505050505050505050565b60608167ffffffffffffffff81111561028f5761028f61050b565b6040519080825280602002602001820160405280156102c257816020015b60608152602001906001900390816102ad5790505b50905060005b828110156103dd57600080308686858181106102e6576102e6610c90565b90506020028101906102f89190610cbf565b604051610306929190610d24565b600060405180830381855af49150503d8060008114610341576040519150601f19603f3d011682016040523d82523d6000602084013e610346565b606091505b5091509150816103b55760448151101561035f57600080fd5b600481019050808060200190518101906103799190610d34565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ac9190610dab565b60405180910390fd5b808484815181106103c8576103c8610c90565b602090810291909101015250506001016102c8565b5092915050565b6040517f3d602d80600a3d3981f30000000000000000000000000000000000000000000060208201527f363d3d373d3d3d363d7300000000000000000000000000000000000000000000602a8201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606084901b1660348201527f5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000604882015260009081906057016040516020818303038152906040529050600083805190602001209050808251602084016000f5925073ffffffffffffffffffffffffffffffffffffffff8316610503576040517f8b1f004000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156105815761058161050b565b604052919050565b600067ffffffffffffffff8211156105a3576105a361050b565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b60006105e26105dd84610589565b61053a565b90508281528383830111156105f657600080fd5b828260208301376000602084830101529392505050565b600082601f83011261061e57600080fd5b61062d838335602085016105cf565b9392505050565b8035801515811461064457600080fd5b919050565b600067ffffffffffffffff8211156106635761066361050b565b5060051b60200190565b803573ffffffffffffffffffffffffffffffffffffffff8116811461064457600080fd5b600082601f8301126106a257600080fd5b813560206106b26105dd83610649565b82815260059290921b840181019181810190868411156106d157600080fd5b8286015b848110156106f3576106e68161066d565b83529183019183016106d5565b509695505050505050565b600082601f83011261070f57600080fd5b8135602061071f6105dd83610649565b82815260059290921b8401810191818101908684111561073e57600080fd5b8286015b848110156106f357803567ffffffffffffffff8111156107625760008081fd5b8701603f810189136107745760008081fd5b6107858986830135604084016105cf565b845250918301918301610742565b60008083601f8401126107a557600080fd5b50813567ffffffffffffffff8111156107bd57600080fd5b6020830191508360208260051b85010111156107d857600080fd5b9250929050565b600082601f8301126107f057600080fd5b60405161020080820182811067ffffffffffffffff821117156108155761081561050b565b6040528301818582111561082857600080fd5b845b8281101561085557803563ffffffff811681146108475760008081fd5b82526020918201910161082a565b509195945050505050565b60008060008060008060008060008060006103008c8e03121561088257600080fd5b67ffffffffffffffff808d35111561089957600080fd5b6108a68e8e358f0161060d565b9b508060208e013511156108b957600080fd5b6108c98e60208f01358f0161060d565b9a508060408e013511156108dc57600080fd5b6108ec8e60408f01358f0161060d565b99506108fa60608e01610634565b98508060808e0135111561090d57600080fd5b61091d8e60808f01358f01610691565b97508060a08e0135111561093057600080fd5b6109408e60a08f01358f016106fe565b96508060c08e0135111561095357600080fd5b6109638e60c08f01358f01610793565b909650945060e08d013581101561097957600080fd5b5061098a8d60e08e01358e01610793565b909350915061099d8d6101008e016107df565b90509295989b509295989b9093969950565b600080602083850312156109c257600080fd5b823567ffffffffffffffff8111156109d957600080fd5b6109e585828601610793565b90969095509350505050565b60005b83811015610a0c5781810151838201526020016109f4565b83811115610a1b576000848401525b50505050565b60008151808452610a398160208601602086016109f1565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600081518084526020808501808196508360051b8101915082860160005b85811015610ab3578284038952610aa1848351610a21565b98850198935090840190600101610a89565b5091979650505050505050565b60208152600061062d6020830184610a6b565b8183526000602080850194508260005b85811015610b1c5773ffffffffffffffffffffffffffffffffffffffff610b098361066d565b1687529582019590820190600101610ae3565b509495945050505050565b81835260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831115610b5957600080fd5b8260051b8083602087013760009401602001938452509192915050565b8060005b6010811015610a1b57815163ffffffff16845260209384019390910190600101610b7a565b6000610300808352610bb38184018f610a21565b9050602083820381850152610bc8828f610a21565b91508382036040850152610bdc828e610a21565b8c1515606086015284810360808601528b51808252828d0193509082019060005b81811015610c2f57845173ffffffffffffffffffffffffffffffffffffffff1683529383019391830191600101610bfd565b505084810360a0860152610c43818c610a6b565b9250505082810360c0840152610c5a81888a610ad3565b905082810360e0840152610c6f818688610b27565b915050610c80610100830184610b76565b9c9b505050505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610cf457600080fd5b83018035915067ffffffffffffffff821115610d0f57600080fd5b6020019150368190038213156107d857600080fd5b8183823760009101908152919050565b600060208284031215610d4657600080fd5b815167ffffffffffffffff811115610d5d57600080fd5b8201601f81018413610d6e57600080fd5b8051610d7c6105dd82610589565b818152856020838501011115610d9157600080fd5b610da28260208301602086016109f1565b95945050505050565b60208152600061062d6020830184610a2156fea2646970667358221220bdb2ae1b307d94c21d1bca8d14c3e98d6f59896c8436e26b68eab4ea0dd5348864736f6c634300080e00330000000000000000000000000d46996d55bb33d32d43e610aac5b64b477e9cbd000000000000000000000000503297a0bf06b1a33124cd93e486f17a7f7fdf20

Deployed Bytecode

0x6080604052600436106100295760003560e01c806309ef16021461002e578063ac9650d81461006b575b600080fd5b61004161003c366004610860565b61008b565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61007e6100793660046109af565b610274565b6040516100629190610ac0565b60006100b77f0000000000000000000000000d46996d55bb33d32d43e610aac5b64b477e9cbd8d6103e4565b6040517f97b55f8100000000000000000000000000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff8216906397b55f8190610120908f908f908f908f908f908f908f908f908f908f908f90600401610b9f565b600060405180830381600087803b15801561013a57600080fd5b505af115801561014e573d6000803e3d6000fd5b50508b518c92506000039050610202576040517f6f0a5e7100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301527f000000000000000000000000503297a0bf06b1a33124cd93e486f17a7f7fdf201690636f0a5e719034906024016000604051808303818588803b1580156101e857600080fd5b505af11580156101fc573d6000803e3d6000fd5b50505050505b8173ffffffffffffffffffffffffffffffffffffffff167f0712ea2ebe8ee974f78171c5f86c898cc0e2858fb69ed676083f8c60ee84ab128e8e8e8e8e8e8e8e8e8e8e60405161025c9b9a99989796959493929190610b9f565b60405180910390a2509b9a5050505050505050505050565b60608167ffffffffffffffff81111561028f5761028f61050b565b6040519080825280602002602001820160405280156102c257816020015b60608152602001906001900390816102ad5790505b50905060005b828110156103dd57600080308686858181106102e6576102e6610c90565b90506020028101906102f89190610cbf565b604051610306929190610d24565b600060405180830381855af49150503d8060008114610341576040519150601f19603f3d011682016040523d82523d6000602084013e610346565b606091505b5091509150816103b55760448151101561035f57600080fd5b600481019050808060200190518101906103799190610d34565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ac9190610dab565b60405180910390fd5b808484815181106103c8576103c8610c90565b602090810291909101015250506001016102c8565b5092915050565b6040517f3d602d80600a3d3981f30000000000000000000000000000000000000000000060208201527f363d3d373d3d3d363d7300000000000000000000000000000000000000000000602a8201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606084901b1660348201527f5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000604882015260009081906057016040516020818303038152906040529050600083805190602001209050808251602084016000f5925073ffffffffffffffffffffffffffffffffffffffff8316610503576040517f8b1f004000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156105815761058161050b565b604052919050565b600067ffffffffffffffff8211156105a3576105a361050b565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b60006105e26105dd84610589565b61053a565b90508281528383830111156105f657600080fd5b828260208301376000602084830101529392505050565b600082601f83011261061e57600080fd5b61062d838335602085016105cf565b9392505050565b8035801515811461064457600080fd5b919050565b600067ffffffffffffffff8211156106635761066361050b565b5060051b60200190565b803573ffffffffffffffffffffffffffffffffffffffff8116811461064457600080fd5b600082601f8301126106a257600080fd5b813560206106b26105dd83610649565b82815260059290921b840181019181810190868411156106d157600080fd5b8286015b848110156106f3576106e68161066d565b83529183019183016106d5565b509695505050505050565b600082601f83011261070f57600080fd5b8135602061071f6105dd83610649565b82815260059290921b8401810191818101908684111561073e57600080fd5b8286015b848110156106f357803567ffffffffffffffff8111156107625760008081fd5b8701603f810189136107745760008081fd5b6107858986830135604084016105cf565b845250918301918301610742565b60008083601f8401126107a557600080fd5b50813567ffffffffffffffff8111156107bd57600080fd5b6020830191508360208260051b85010111156107d857600080fd5b9250929050565b600082601f8301126107f057600080fd5b60405161020080820182811067ffffffffffffffff821117156108155761081561050b565b6040528301818582111561082857600080fd5b845b8281101561085557803563ffffffff811681146108475760008081fd5b82526020918201910161082a565b509195945050505050565b60008060008060008060008060008060006103008c8e03121561088257600080fd5b67ffffffffffffffff808d35111561089957600080fd5b6108a68e8e358f0161060d565b9b508060208e013511156108b957600080fd5b6108c98e60208f01358f0161060d565b9a508060408e013511156108dc57600080fd5b6108ec8e60408f01358f0161060d565b99506108fa60608e01610634565b98508060808e0135111561090d57600080fd5b61091d8e60808f01358f01610691565b97508060a08e0135111561093057600080fd5b6109408e60a08f01358f016106fe565b96508060c08e0135111561095357600080fd5b6109638e60c08f01358f01610793565b909650945060e08d013581101561097957600080fd5b5061098a8d60e08e01358e01610793565b909350915061099d8d6101008e016107df565b90509295989b509295989b9093969950565b600080602083850312156109c257600080fd5b823567ffffffffffffffff8111156109d957600080fd5b6109e585828601610793565b90969095509350505050565b60005b83811015610a0c5781810151838201526020016109f4565b83811115610a1b576000848401525b50505050565b60008151808452610a398160208601602086016109f1565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600081518084526020808501808196508360051b8101915082860160005b85811015610ab3578284038952610aa1848351610a21565b98850198935090840190600101610a89565b5091979650505050505050565b60208152600061062d6020830184610a6b565b8183526000602080850194508260005b85811015610b1c5773ffffffffffffffffffffffffffffffffffffffff610b098361066d565b1687529582019590820190600101610ae3565b509495945050505050565b81835260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831115610b5957600080fd5b8260051b8083602087013760009401602001938452509192915050565b8060005b6010811015610a1b57815163ffffffff16845260209384019390910190600101610b7a565b6000610300808352610bb38184018f610a21565b9050602083820381850152610bc8828f610a21565b91508382036040850152610bdc828e610a21565b8c1515606086015284810360808601528b51808252828d0193509082019060005b81811015610c2f57845173ffffffffffffffffffffffffffffffffffffffff1683529383019391830191600101610bfd565b505084810360a0860152610c43818c610a6b565b9250505082810360c0840152610c5a81888a610ad3565b905082810360e0840152610c6f818688610b27565b915050610c80610100830184610b76565b9c9b505050505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610cf457600080fd5b83018035915067ffffffffffffffff821115610d0f57600080fd5b6020019150368190038213156107d857600080fd5b8183823760009101908152919050565b600060208284031215610d4657600080fd5b815167ffffffffffffffff811115610d5d57600080fd5b8201601f81018413610d6e57600080fd5b8051610d7c6105dd82610589565b818152856020838501011115610d9157600080fd5b610da28260208301602086016109f1565b95945050505050565b60208152600061062d6020830184610a2156fea2646970667358221220bdb2ae1b307d94c21d1bca8d14c3e98d6f59896c8436e26b68eab4ea0dd5348864736f6c634300080e0033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000000d46996d55bb33d32d43e610aac5b64b477e9cbd000000000000000000000000503297a0bf06b1a33124cd93e486f17a7f7fdf20

-----Decoded View---------------
Arg [0] : kaliMaster_ (address): 0x0D46996D55bB33D32D43E610aac5B64b477e9cBD
Arg [1] : ricardianLLC_ (address): 0x503297a0bf06B1A33124Cd93e486f17A7F7fDF20

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000000d46996d55bb33d32d43e610aac5b64b477e9cbd
Arg [1] : 000000000000000000000000503297a0bf06b1a33124cd93e486f17a7f7fdf20


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Txn Hash Block Value Eth2 PubKey Valid
View All Deposits
[ 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.