Goerli Testnet

Contract

0xDDdFf70C77Cffcf97Fb91F7aC4aD0E12E8C14571
Source Code
Transaction Hash
Method
Block
From
To
Value
Deploy Kali DAO102268812023-12-17 12:36:2470 days 9 hrs ago1702816584IN
0xDDdFf7...E8C14571
0 ETH0.001112271.50000002
Deploy Kali DAO101278662023-11-29 14:57:2488 days 6 hrs ago1701269844IN
0xDDdFf7...E8C14571
0 ETH0.000999641.50000023
Deploy Kali DAO100834472023-11-21 17:35:2496 days 4 hrs ago1700588124IN
0xDDdFf7...E8C14571
0 ETH0.001177461.50000001
Deploy Kali DAO100821792023-11-21 12:17:0096 days 9 hrs ago1700569020IN
0xDDdFf7...E8C14571
0 ETH0.000999621.50000001
Deploy Kali DAO99925562023-11-05 21:24:36112 days 30 mins ago1699219476IN
0xDDdFf7...E8C14571
0 ETH0.000999741.5
Deploy Kali DAO98746202023-10-16 4:35:12132 days 17 hrs ago1697430912IN
0xDDdFf7...E8C14571
0 ETH0.000999941.5
Deploy Kali DAO98447432023-10-10 22:52:48137 days 23 hrs ago1696978368IN
0xDDdFf7...E8C14571
0 ETH0.000999671.5
Deploy Kali DAO97395322023-09-22 12:40:00156 days 9 hrs ago1695386400IN
0xDDdFf7...E8C14571
0 ETH0.000853961.50000003
Deploy Kali DAO96612542023-09-08 23:43:36169 days 22 hrs ago1694216616IN
0xDDdFf7...E8C14571
0 ETH0.001112431.5
Deploy Kali DAO96001672023-08-29 8:26:24180 days 13 hrs ago1693297584IN
0xDDdFf7...E8C14571
0 ETH00.00000021
Deploy Kali DAO93099262023-07-08 7:27:24232 days 14 hrs ago1688801244IN
0xDDdFf7...E8C14571
0 ETH0.001263941.50000002
Deploy Kali DAO92657712023-06-30 10:29:48240 days 11 hrs ago1688120988IN
0xDDdFf7...E8C14571
0 ETH0.000999611.50001209
Deploy Kali DAO92166252023-06-21 17:11:12249 days 4 hrs ago1687367472IN
0xDDdFf7...E8C14571
0 ETH0.001337991.50015242
Deploy Kali DAO90846842023-05-29 10:23:24272 days 11 hrs ago1685355804IN
0xDDdFf7...E8C14571
0 ETH0.001177771.76732915
Deploy Kali DAO89313972023-05-02 22:58:24298 days 22 hrs ago1683068304IN
0xDDdFf7...E8C14571
0 ETH0.0445999166.92152094
Deploy Kali DAO89234362023-05-01 13:11:24300 days 8 hrs ago1682946684IN
0xDDdFf7...E8C14571
0 ETH0.0117676517.65719946
Deploy Kali DAO88968252023-04-26 20:54:00305 days 1 hr ago1682542440IN
0xDDdFf7...E8C14571
0 ETH0.005617718.42854546
Deploy Kali DAO88957402023-04-26 16:21:36305 days 5 hrs ago1682526096IN
0xDDdFf7...E8C14571
0 ETH0.0195316121.89554628
Deploy Kali DAO88366552023-04-15 23:24:00315 days 22 hrs ago1681601040IN
0xDDdFf7...E8C14571
0 ETH0.007039399.05972246
Deploy Kali DAO87396032023-03-29 17:45:24333 days 4 hrs ago1680111924IN
0xDDdFf7...E8C14571
0 ETH0.08330772117.68573099
Deploy Kali DAO87230772023-03-26 20:12:12336 days 1 hr ago1679861532IN
0xDDdFf7...E8C14571
0 ETH0.0226512131.38269467
Deploy Kali DAO86848082023-03-20 1:11:00342 days 20 hrs ago1679274660IN
0xDDdFf7...E8C14571
0 ETH0.001432611.75357459
Deploy Kali DAO86282092023-03-10 3:26:12352 days 18 hrs ago1678418772IN
0xDDdFf7...E8C14571
0 ETH0.0162995521.97433692
Deploy Kali DAO85664132023-02-27 13:46:00363 days 8 hrs ago1677505560IN
0xDDdFf7...E8C14571
0 ETH0.01734726.02814956
Deploy Kali DAO85251422023-02-20 13:52:48370 days 8 hrs ago1676901168IN
0xDDdFf7...E8C14571
0 ETH0.0227728327.88110357
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Txn Hash Block From To Value
102268812023-12-17 12:36:2470 days 9 hrs ago1702816584
0xDDdFf7...E8C14571
0 ETH
102268812023-12-17 12:36:2470 days 9 hrs ago1702816584
0xDDdFf7...E8C14571
 Contract Creation0 ETH
101278662023-11-29 14:57:2488 days 6 hrs ago1701269844
0xDDdFf7...E8C14571
0 ETH
101278662023-11-29 14:57:2488 days 6 hrs ago1701269844
0xDDdFf7...E8C14571
 Contract Creation0 ETH
100834472023-11-21 17:35:2496 days 4 hrs ago1700588124
0xDDdFf7...E8C14571
0 ETH
100834472023-11-21 17:35:2496 days 4 hrs ago1700588124
0xDDdFf7...E8C14571
 Contract Creation0 ETH
100821792023-11-21 12:17:0096 days 9 hrs ago1700569020
0xDDdFf7...E8C14571
0 ETH
100821792023-11-21 12:17:0096 days 9 hrs ago1700569020
0xDDdFf7...E8C14571
 Contract Creation0 ETH
99925562023-11-05 21:24:36112 days 30 mins ago1699219476
0xDDdFf7...E8C14571
0 ETH
99925562023-11-05 21:24:36112 days 30 mins ago1699219476
0xDDdFf7...E8C14571
 Contract Creation0 ETH
98746202023-10-16 4:35:12132 days 17 hrs ago1697430912
0xDDdFf7...E8C14571
0 ETH
98746202023-10-16 4:35:12132 days 17 hrs ago1697430912
0xDDdFf7...E8C14571
 Contract Creation0 ETH
98447432023-10-10 22:52:48137 days 23 hrs ago1696978368
0xDDdFf7...E8C14571
0 ETH
98447432023-10-10 22:52:48137 days 23 hrs ago1696978368
0xDDdFf7...E8C14571
 Contract Creation0 ETH
97395322023-09-22 12:40:00156 days 9 hrs ago1695386400
0xDDdFf7...E8C14571
0 ETH
97395322023-09-22 12:40:00156 days 9 hrs ago1695386400
0xDDdFf7...E8C14571
 Contract Creation0 ETH
96612542023-09-08 23:43:36169 days 22 hrs ago1694216616
0xDDdFf7...E8C14571
0 ETH
96612542023-09-08 23:43:36169 days 22 hrs ago1694216616
0xDDdFf7...E8C14571
 Contract Creation0 ETH
96001672023-08-29 8:26:24180 days 13 hrs ago1693297584
0xDDdFf7...E8C14571
0 ETH
96001672023-08-29 8:26:24180 days 13 hrs ago1693297584
0xDDdFf7...E8C14571
 Contract Creation0 ETH
93099262023-07-08 7:27:24232 days 14 hrs ago1688801244
0xDDdFf7...E8C14571
0 ETH
93099262023-07-08 7:27:24232 days 14 hrs ago1688801244
0xDDdFf7...E8C14571
 Contract Creation0 ETH
92657712023-06-30 10:29:48240 days 11 hrs ago1688120988
0xDDdFf7...E8C14571
0 ETH
92657712023-06-30 10:29:48240 days 11 hrs ago1688120988
0xDDdFf7...E8C14571
 Contract Creation0 ETH
92166252023-06-21 17:11:12249 days 4 hrs ago1687367472
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.