ERC-20
Overview
Max Total Supply
4,001 LootexDAO
Holders
3
Market
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract (WITH 18 Decimals)
Balance
1,000 LootexDAOValue
$0.00Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Minimal Proxy Contract for 0xfc0fd933d8ef5b7e552e67acfc4c09711b413f30
Contract Name:
KaliDAO
Compiler Version
v0.8.11+commit.d7f03943
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2022-02-14 */ // 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); } }
[{"inputs":[],"name":"AlreadyVoted","type":"error"},{"inputs":[],"name":"InitCallFail","type":"error"},{"inputs":[],"name":"Initialized","type":"error"},{"inputs":[],"name":"InvalidNonce","type":"error"},{"inputs":[],"name":"InvalidSignature","type":"error"},{"inputs":[],"name":"NoArrayParity","type":"error"},{"inputs":[],"name":"NotCurrentProposal","type":"error"},{"inputs":[],"name":"NotDetermined","type":"error"},{"inputs":[],"name":"NotExtension","type":"error"},{"inputs":[],"name":"NotMember","type":"error"},{"inputs":[],"name":"NotProposer","type":"error"},{"inputs":[],"name":"NotVoteable","type":"error"},{"inputs":[],"name":"NullAddress","type":"error"},{"inputs":[],"name":"Paused","type":"error"},{"inputs":[],"name":"PeriodBounds","type":"error"},{"inputs":[],"name":"PrevNotProcessed","type":"error"},{"inputs":[],"name":"QuorumMax","type":"error"},{"inputs":[],"name":"Reentrancy","type":"error"},{"inputs":[],"name":"SignatureExpired","type":"error"},{"inputs":[],"name":"Sponsored","type":"error"},{"inputs":[],"name":"SupermajorityBounds","type":"error"},{"inputs":[],"name":"TypeBounds","type":"error"},{"inputs":[],"name":"Uint32max","type":"error"},{"inputs":[],"name":"Uint96max","type":"error"},{"inputs":[],"name":"VotingNotEnded","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegator","type":"address"},{"indexed":true,"internalType":"address","name":"fromDelegate","type":"address"},{"indexed":true,"internalType":"address","name":"toDelegate","type":"address"}],"name":"DelegateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegate","type":"address"},{"indexed":false,"internalType":"uint256","name":"previousBalance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newBalance","type":"uint256"}],"name":"DelegateVotesChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"proposer","type":"address"},{"indexed":true,"internalType":"uint256","name":"proposal","type":"uint256"},{"indexed":true,"internalType":"enum KaliDAO.ProposalType","name":"proposalType","type":"uint8"},{"indexed":false,"internalType":"string","name":"description","type":"string"},{"indexed":false,"internalType":"address[]","name":"accounts","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"indexed":false,"internalType":"bytes[]","name":"payloads","type":"bytes[]"}],"name":"NewProposal","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"paused","type":"bool"}],"name":"PauseFlipped","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"proposer","type":"address"},{"indexed":true,"internalType":"uint256","name":"proposal","type":"uint256"}],"name":"ProposalCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"proposal","type":"uint256"},{"indexed":true,"internalType":"bool","name":"didProposalPass","type":"bool"}],"name":"ProposalProcessed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sponsor","type":"address"},{"indexed":true,"internalType":"uint256","name":"proposal","type":"uint256"}],"name":"ProposalSponsored","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"voter","type":"address"},{"indexed":true,"internalType":"uint256","name":"proposal","type":"uint256"},{"indexed":true,"internalType":"bool","name":"approve","type":"bool"}],"name":"VoteCast","type":"event"},{"inputs":[],"name":"DELEGATION_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VOTE_HASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnShares","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"extension","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"extensionData","type":"bytes"}],"name":"callExtension","outputs":[{"internalType":"bool","name":"mint","type":"bool"},{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposal","type":"uint256"}],"name":"cancelProposal","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"checkpoints","outputs":[{"internalType":"uint32","name":"fromTimestamp","type":"uint32"},{"internalType":"uint96","name":"votes","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"}],"name":"delegate","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"delegateBySig","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"delegator","type":"address"}],"name":"delegates","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"docs","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"extensions","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getCurrentVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"getPriorVotes","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposal","type":"uint256"}],"name":"getProposalArrays","outputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes[]","name":"payloads","type":"bytes[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gracePeriod","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"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":"init","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastYesVote","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mintShares","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"multicall","outputs":[{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"numCheckpoints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"sig","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"sig","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"sig","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposal","type":"uint256"}],"name":"processProposal","outputs":[{"internalType":"bool","name":"didProposalPass","type":"bool"},{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"proposalCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"proposalStates","outputs":[{"internalType":"bool","name":"passed","type":"bool"},{"internalType":"bool","name":"processed","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum KaliDAO.ProposalType","name":"","type":"uint8"}],"name":"proposalVoteTypes","outputs":[{"internalType":"enum KaliDAO.VoteType","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"proposals","outputs":[{"internalType":"enum KaliDAO.ProposalType","name":"proposalType","type":"uint8"},{"internalType":"string","name":"description","type":"string"},{"internalType":"uint256","name":"prevProposal","type":"uint256"},{"internalType":"uint96","name":"yesVotes","type":"uint96"},{"internalType":"uint96","name":"noVotes","type":"uint96"},{"internalType":"uint32","name":"creationTime","type":"uint32"},{"internalType":"address","name":"proposer","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum KaliDAO.ProposalType","name":"proposalType","type":"uint8"},{"internalType":"string","name":"description","type":"string"},{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes[]","name":"payloads","type":"bytes[]"}],"name":"propose","outputs":[{"internalType":"uint256","name":"proposal","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"quorum","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposal","type":"uint256"}],"name":"sponsorProposal","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"supermajority","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposal","type":"uint256"},{"internalType":"bool","name":"approve","type":"bool"}],"name":"vote","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"uint256","name":"proposal","type":"uint256"},{"internalType":"bool","name":"approve","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"voteBySig","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"voted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"votingPeriod","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.