ETH Price: $3,307.05 (+1.76%)
Gas: 3 Gwei

Token

parknsleep AG Shares SHA (PNS)
 

Overview

Max Total Supply

320,040 PNS

Holders

387

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 0 Decimals)

Balance
100 PNS

Value
$0.00
0xfe05f54fc5b6f36018c1addeac8a8e6000bfef66
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

Similar Match Source Code
This contract matches the deployed Bytecode of the Source Code for Contract 0x4c9cc826...7cB4EfDA9
The constructor portion of the code might be different and could alter the actual behaviour of the contract

Contract Name:
DraggableShares

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license
File 1 of 14 : ERC20Flaggable.sol
// SPDX-License-Identifier: MIT
// Copied and adjusted from OpenZeppelin
// Adjustments:
// - modifications to support ERC-677
// - removed unnecessary require statements
// - removed GSN Context
// - upgraded to 0.8 to drop SafeMath
// - let name() and symbol() be implemented by subclass
// - infinite allowance support, with 2^255 and above considered infinite
// - use upper 32 bits of balance for flags
// - add a global settings variable

pragma solidity ^0.8.0;

import "./IERC20.sol";
import "./IERC677Receiver.sol";

/**
 * @dev Implementation of the `IERC20` interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using `_mint`.
 * For a generic mechanism see `ERC20Mintable`.
 *
 * *For a detailed writeup see our guide [How to implement supply
 * mechanisms](https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226).*
 *
 * We have followed general OpenZeppelin guidelines: functions revert instead
 * of returning `false` on failure. This behavior is nonetheless conventional
 * and does not conflict with the expectations of ERC20 applications.
 *
 * Additionally, an `Approval` event is emitted on calls to `transferFrom`.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard `decreaseAllowance` and `increaseAllowance`
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See `IERC20.approve`.
 */

abstract contract ERC20Flaggable is IERC20 {

    // as Documented in /doc/infiniteallowance.md
    // 0x8000000000000000000000000000000000000000000000000000000000000000
    uint256 constant private INFINITE_ALLOWANCE = 2**255;

    uint256 private constant FLAGGING_MASK = 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000;

    // Documentation of flags used by subclasses:
    // NOTE: flags denote the bit number that is being used and must be smaller than 32
    // ERC20Draggable: uint8 private constant FLAG_INDEX_VOTED = 1;
    // ERC20Recoverable: uint8 private constant FLAG_INDEX_CLAIM_PRESENT = 10;
    // ERCAllowlistable: uint8 private constant FLAG_INDEX_ALLOWLIST = 20;
    // ERCAllowlistable: uint8 private constant FLAG_INDEX_FORBIDDEN = 21;
    // ERCAllowlistable: uint8 private constant FLAG_INDEX_POWERLIST = 22;

    mapping (address => uint256) private _balances; // upper 32 bits reserved for flags

    mapping (address => mapping (address => uint256)) private _allowances;

    uint256 private _totalSupply;

    uint8 public override decimals;

    event NameChanged(string name, string symbol);

    constructor(uint8 _decimals) {
        decimals = _decimals;
    }

    /**
     * @dev See `IERC20.totalSupply`.
     */
    function totalSupply() public view override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See `IERC20.balanceOf`.
     */
    function balanceOf(address account) public view override returns (uint256) {
        return uint224 (_balances [account]);
    }

    function hasFlag(address account, uint8 number) external view returns (bool) {
        return hasFlagInternal(account, number);
    }

    function setFlag(address account, uint8 index, bool value) internal {
        uint256 flagMask = 1 << (index + 224);
        uint256 balance = _balances [account];
        if ((balance & flagMask == flagMask) != value) {
            _balances [account] = balance ^ flagMask;
        }
    }

    function hasFlagInternal(address account, uint8 number) internal view returns (bool) {
        uint256 flag = 0x1 << (number + 224);
        return _balances[account] & flag == flag;
    }

    /**
     * @dev See `IERC20.transfer`.
     *
     * Requirements:
     *
     * - `recipient` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(msg.sender, recipient, amount);
        return true;
    }

    /**
     * @dev See `IERC20.allowance`.
     */
    function allowance(address owner, address spender) external view override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See `IERC20.approve`.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 value) external override returns (bool) {
        _approve(msg.sender, spender, value);
        return true;
    }

    /**
     * @dev See `IERC20.transferFrom`.
     *
     * Emits an `Approval` event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of `ERC20`;
     *
     * Requirements:
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `value`.
     * - the caller must have allowance for `sender`'s tokens of at least
     * `amount`.
     */
    function transferFrom(address sender, address recipient, uint256 amount) external override returns (bool) {
        _transfer(sender, recipient, amount);
        uint256 currentAllowance = _allowances[sender][msg.sender];
        if (currentAllowance < INFINITE_ALLOWANCE){
            // Only decrease the allowance if it was not set to 'infinite'
            // Documented in /doc/infiniteallowance.md
            _allowances[sender][msg.sender] = currentAllowance - amount;
        }
        return true;
    }

    /**
     * @dev Moves tokens `amount` from `sender` to `recipient`.
     *
     * This is internal function is equivalent to `transfer`, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a `Transfer` event.
     *
     * Requirements:
     *
     * - `sender` cannot be the zero address.
     * - `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     */
    function _transfer(address sender, address recipient, uint256 amount) internal virtual {
        _beforeTokenTransfer(sender, recipient, amount);
        decreaseBalance(sender, amount);
        increaseBalance(recipient, amount);
        emit Transfer(sender, recipient, amount);
    }

    // ERC-677 functionality, can be useful for swapping and wrapping tokens
    function transferAndCall(address recipient, uint amount, bytes calldata data) external virtual returns (bool) {
        return transfer (recipient, amount) 
            && IERC677Receiver (recipient).onTokenTransfer (msg.sender, amount, data);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a `Transfer` event with `from` set to the zero address.
     *
     * Requirements
     *
     * - `to` cannot be the zero address.
     */
    function _mint(address recipient, uint256 amount) internal virtual {
        _beforeTokenTransfer(address(0), recipient, amount);
        _totalSupply += amount;
        increaseBalance(recipient, amount);
        emit Transfer(address(0), recipient, amount);
    }

    function increaseBalance(address recipient, uint256 amount) private {
        require(recipient != address(0x0), "0x0"); // use burn instead
        uint256 oldBalance = _balances[recipient];
        uint256 newBalance = oldBalance + amount;
        require(oldBalance & FLAGGING_MASK == newBalance & FLAGGING_MASK, "overflow");
        _balances[recipient] = newBalance;
    }

     /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a `Transfer` event with `to` set to the zero address.
     *
     * Requirements
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        _beforeTokenTransfer(account, address(0), amount);

        _totalSupply -= amount;
        decreaseBalance(account, amount);
        emit Transfer(account, address(0), amount);
    }

    function decreaseBalance(address sender, uint256 amount) private {
        uint256 oldBalance = _balances[sender];
        uint256 newBalance = oldBalance - amount;
        require(oldBalance & FLAGGING_MASK == newBalance & FLAGGING_MASK, "underflow");
        _balances[sender] = newBalance;
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.
     *
     * This is internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an `Approval` event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(address owner, address spender, uint256 value) internal {
        _allowances[owner][spender] = value;
        emit Approval(owner, spender, value);
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be to transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
     // solhint-disable-next-line no-empty-blocks
    function _beforeTokenTransfer(address from, address to, uint256 amount) virtual internal {
        // intentionally left blank
    }

}

File 2 of 14 : ERC20PermitLight.sol
// SPDX-License-Identifier: MIT
// Copied from https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol
// and modified it.

pragma solidity ^0.8.0;

import "./ERC20Flaggable.sol";
import "./IERC20Permit.sol";

abstract contract ERC20PermitLight is ERC20Flaggable, IERC20Permit {
   
   /*//////////////////////////////////////////////////////////////
                            EIP-2612 STORAGE
    //////////////////////////////////////////////////////////////*/

    mapping(address => uint256) public override nonces;

  /*//////////////////////////////////////////////////////////////
                             EIP-2612 LOGIC
    //////////////////////////////////////////////////////////////*/

    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public override {
        require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");

        unchecked { // unchecked to save a little gas with the nonce increment...
            address recoveredAddress = ecrecover(
                keccak256(
                    abi.encodePacked(
                        "\x19\x01",
                        DOMAIN_SEPARATOR(),
                        keccak256(
                            abi.encode(
                                // keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"),
                                bytes32(0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9),
                                owner,
                                spender,
                                value,
                                nonces[owner]++,
                                deadline
                            )
                        )
                    )
                ),
                v,
                r,
                s
            );

            require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");
            _approve(recoveredAddress, spender, value);
        }
    }

    function DOMAIN_SEPARATOR() public view override returns (bytes32) {
        return
            keccak256(
                abi.encode(
                    //keccak256("EIP712Domain(uint256 chainId,address verifyingContract)");
                    bytes32(0x47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a79469218),
                    block.chainid,
                    address(this)
                )
            );
    }

}

File 3 of 14 : IERC20.sol
/**
* SPDX-License-Identifier: MIT
*
* Copyright (c) 2016-2019 zOS Global Limited
*
*/
pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP. Does not include
 * the optional functions; to access them see `ERC20Detailed`.
 */

interface IERC20 {

    // Optional functions
    function name() external view returns (string memory);

    function symbol() external view returns (string memory);

    function decimals() external view returns (uint8);

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a `Transfer` event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through `transferFrom`. This is
     * zero by default.
     *
     * This value changes when `approve` or `transferFrom` are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * > Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an `Approval` event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a `Transfer` event.
     */
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to `approve`. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

}

File 4 of 14 : IERC20Permit.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)
// Copied from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/extensions/draft-IERC20Permit.sol

pragma solidity ^0.8.0;

import "./IERC20.sol";

/**
 * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 */
interface IERC20Permit is IERC20 {
    /**
     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
     * given ``owner``'s signed approval.
     *
     * IMPORTANT: The same issues {IERC20-approve} has related to transaction
     * ordering also apply here.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `deadline` must be a timestamp in the future.
     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
     * over the EIP712-formatted function arguments.
     * - the signature must use ``owner``'s current nonce (see {nonces}).
     *
     * For more information on the signature format, see the
     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
     * section].
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    /**
     * @dev Returns the current nonce for `owner`. This value must be
     * included whenever a signature is generated for {permit}.
     *
     * Every successful call to {permit} increases ``owner``'s nonce by one. This
     * prevents a signature from being used multiple times.
     */
    function nonces(address owner) external view returns (uint256);

    /**
     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

File 5 of 14 : IERC677Receiver.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// Given that development on ERC 677 has stalled, we should consider supporting EIP 1363: https://eips.ethereum.org/EIPS/eip-1363
interface IERC677Receiver {
    
    function onTokenTransfer(address from, uint256 amount, bytes calldata data) external returns (bool);

}

File 6 of 14 : ERC20Draggable.sol
/**
 * SPDX-License-Identifier: LicenseRef-Aktionariat
 *
 * MIT License with Automated License Fee Payments
 *
 * Copyright (c) 2022 Aktionariat AG (aktionariat.com)
 *
 * Permission is hereby granted to any person obtaining a copy of this software
 * and associated documentation files (the "Software"), to deal in the Software
 * without restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies of the
 * Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * - The above copyright notice and this permission notice shall be included in
 *   all copies or substantial portions of the Software.
 * - All automated license fee payments integrated into this and related Software
 *   are preserved.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
pragma solidity ^0.8.0;

/**
 * @title ERC-20 tokens subject to a drag-along agreement
 * @author Luzius Meisser, [email protected]
 *
 * This is an ERC-20 token that is bound to a shareholder or other agreement that contains
 * a drag-along clause. The smart contract can help enforce this drag-along clause in case
 * an acquirer makes an offer using the provided functionality. If a large enough quorum of
 * token holders agree, the remaining token holders can be automatically "dragged along" or
 * squeezed out. For shares non-tokenized shares, the contract relies on an external Oracle
 * to provide the votes of those.
 *
 * Subclasses should provide a link to a human-readable form of the agreement.
 */

import "./IDraggable.sol";
import "../ERC20/ERC20Flaggable.sol";
import "../ERC20/IERC20.sol";
import "../ERC20/IERC677Receiver.sol";
import "./IOffer.sol";
import "./IOfferFactory.sol";
import "../shares/IShares.sol";

abstract contract ERC20Draggable is IERC677Receiver, IDraggable, ERC20Flaggable {
    
	// If flag is not present, one can be sure that the address did not vote. If the 
	// flag is present, the address might have voted and one needs to check with the
	// current offer (if any) when transferring tokens.
	uint8 private constant FLAG_VOTE_HINT = 1;

	IERC20 public override wrapped; // The wrapped contract
	IOfferFactory public immutable factory;

	// If the wrapped tokens got replaced in an acquisition, unwrapping might yield many currency tokens
	uint256 public unwrapConversionFactor = 0;

	// The current acquisition attempt, if any. See initiateAcquisition to see the requirements to make a public offer.
	IOffer public override offer;

	uint256 private constant QUORUM_MULTIPLIER = 10000;

	uint256 public immutable quorumMigration; // used for contract migartion, in BPS (out of 10'000) 
	uint256 public immutable quorum; // used for drag-along at acquisition offers, in BPS (out of 10'000)
	uint256 public immutable votePeriod; // In seconds

	address public override oracle;

	event MigrationSucceeded(address newContractAddress, uint256 yesVotes, uint256 oracleVotes, uint256 totalVotingPower);
	event ChangeOracle(address oracle);

    /**
	 * Note that the Brokerbot only supports tokens that revert on failure and where transfer never returns false.
     */
	constructor(
		IERC20 _wrappedToken,
		uint256 _quorum,
		uint256 _quorumMigration,
		uint256 _votePeriod,
		IOfferFactory _offerFactory,
		address _oracle
	) 
		ERC20Flaggable(0)
	{
		wrapped = _wrappedToken;
		quorum = _quorum;
		quorumMigration = _quorumMigration;
		votePeriod = _votePeriod;
		factory = _offerFactory;
		oracle = _oracle;
	}

	function onTokenTransfer(
		address from, 
		uint256 amount, 
		bytes calldata
	) external override returns (bool) {
		require(msg.sender == address(wrapped), "sender");
		_mint(from, amount);
		return true;
	}

	/** Wraps additional tokens, thereby creating more ERC20Draggable tokens. */
	function wrap(address shareholder, uint256 amount) external {
		require(wrapped.transferFrom(msg.sender, address(this), amount), "transfer");
		_mint(shareholder, amount);
	}

	/**
	 * Indicates that the token holders are bound to the token terms and that:
	 * - Conversion back to the wrapped token (unwrap) is not allowed
	 * - A drag-along can be performed by making an according offer
	 * - They can be migrated to a new version of this contract in accordance with the terms
	 */
	function isBinding() public view returns (bool) {
		return unwrapConversionFactor == 0;
	}

    /**
	 * Current recommended naming convention is to add the postfix "SHA" to the plain shares
	 * in order to indicate that this token represents shares bound to a shareholder agreement.
	 */
	function name() public view override returns (string memory) {
		string memory wrappedName = wrapped.name();
		if (isBinding()) {
			return string(abi.encodePacked(wrappedName, " SHA"));
		} else {
			return string(abi.encodePacked(wrappedName, " (Wrapped)"));
		}
	}

	function symbol() public view override returns (string memory) {
		// ticker should be less dynamic than name
		return string(abi.encodePacked(wrapped.symbol(), "S"));
	}

	/**
	 * Deactivates the drag-along mechanism and enables the unwrap function.
	 */
	function deactivate(uint256 factor) internal {
		require(factor >= 1, "factor");
		unwrapConversionFactor = factor;
		emit NameChanged(name(), symbol());
	}

	/** Decrease the number of drag-along tokens. The user gets back their shares in return */
	function unwrap(uint256 amount) external override{
		require(!isBinding(), "factor");
		unwrap(msg.sender, amount, unwrapConversionFactor);
	}

	function unwrap(address owner, uint256 amount, uint256 factor) internal {
		_burn(owner, amount);
		require(wrapped.transfer(owner, amount * factor), "transfer");
	}

	/**
	 * Burns both the token itself as well as the wrapped token!
	 * If you want to get out of the shareholder agreement, use unwrap after it has been
	 * deactivated by a majority vote or acquisition.
	 *
	 * Burning only works if wrapped token supports burning. Also, the exact meaning of this
	 * operation might depend on the circumstances. Burning and reussing the wrapped token
	 * does not free the sender from the legal obligations of the shareholder agreement.
	 */
	function burn(uint256 amount) external {
		_burn(msg.sender, amount);
		IShares(address(wrapped)).burn (isBinding() ? amount : amount * unwrapConversionFactor);
	}

	function makeAcquisitionOffer(
		bytes32 salt, 
		uint256 pricePerShare, 
		IERC20 currency
	) external payable {
		require(isBinding(), "factor");
		IOffer newOffer = factory.create{value: msg.value}(
			salt, msg.sender, pricePerShare, currency, quorum, votePeriod);

		if (offerExists()) {
			offer.makeCompetingOffer(newOffer);
		}
		offer = newOffer;
	}

	function drag(address buyer, IERC20 currency) external override offerOnly {
		unwrap(buyer, balanceOf(buyer), 1);
		replaceWrapped(currency, buyer);
	}

	function notifyOfferEnded() external override offerOnly {
		offer = IOffer(address(0));
	}

	function replaceWrapped(IERC20 newWrapped, address oldWrappedDestination) internal {
		require(isBinding(), "factor");
		// Free all old wrapped tokens we have
		require(wrapped.transfer(oldWrappedDestination, wrapped.balanceOf(address(this))), "transfer");
		// Count the new wrapped tokens
		wrapped = newWrapped;
		deactivate(newWrapped.balanceOf(address(this)) / totalSupply());
	}

	function setOracle(address newOracle) external {
		require(msg.sender == oracle, "not oracle");
		oracle = newOracle;
		emit ChangeOracle(oracle);
	}

	function migrateWithExternalApproval(address successor, uint256 additionalVotes) external {
		require(msg.sender == oracle, "not oracle");
		// Additional votes cannot be higher than the votes not represented by these tokens.
		// The assumption here is that more shareholders are bound to the shareholder agreement
		// that this contract helps enforce and a vote among all parties is necessary to change
		// it, with an oracle counting and reporting the votes of the others.
		require(totalSupply() + additionalVotes <= totalVotingTokens(), "votes");
		migrate(successor, additionalVotes);
	}

	function migrate() external {
		migrate(msg.sender, 0);
	}

	function migrate(address successor, uint256 additionalVotes) internal {
		uint256 yesVotes = additionalVotes + balanceOf(successor);
		uint256 totalVotes = totalVotingTokens();
		require(yesVotes <= totalVotes, "votes");
		require(!offerExists(), "no offer"); // if you have the quorum, you can cancel the offer first if necessary
		require(yesVotes * QUORUM_MULTIPLIER >= totalVotes * quorumMigration, "quorum");
		replaceWrapped(IERC20(successor), successor);
		emit MigrationSucceeded(successor, yesVotes, additionalVotes, totalVotes);
	}

	function votingPower(address voter) external view override returns (uint256) {
		return balanceOf(voter);
	}

	function totalVotingTokens() public view override returns (uint256) {
		return IShares(address(wrapped)).totalShares();
	}

	function hasVoted(address voter) internal view returns (bool) {
		return hasFlagInternal(voter, FLAG_VOTE_HINT);
	}

	function notifyVoted(address voter) external override offerOnly {
		setFlag(voter, FLAG_VOTE_HINT, true);
	}

	modifier offerOnly(){
		require(msg.sender == address(offer), "sender");
		_;
	}

	function _beforeTokenTransfer(address from, address to,	uint256 amount) internal virtual override {
		if (hasVoted(from) || hasVoted(to)) {
			if (offerExists()) {
				offer.notifyMoved(from, to, amount);
			} else {
				setFlag(from, FLAG_VOTE_HINT, false);
				setFlag(to, FLAG_VOTE_HINT, false);
			}
		}
		super._beforeTokenTransfer(from, to, amount);
	}

	function offerExists() internal view returns (bool) {
		return address(offer) != address(0);
	}
}

File 7 of 14 : IDraggable.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "../ERC20/IERC20.sol";
import "./IOffer.sol";
interface IDraggable {
    
    function wrapped() external view returns (IERC20);
    function unwrap(uint256 amount) external;
    function offer() external view returns (IOffer);
    function oracle() external view returns (address);
    function drag(address buyer, IERC20 currency) external;
    function notifyOfferEnded() external;
    function votingPower(address voter) external returns (uint256);
    function totalVotingTokens() external view returns (uint256);
    function notifyVoted(address voter) external;

}

File 8 of 14 : IOffer.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "../ERC20/IERC20.sol";

interface IOffer {
	function makeCompetingOffer(IOffer newOffer) external;

	// if there is a token transfer while an offer is open, the votes get transfered too
	function notifyMoved(address from, address to, uint256 value) external;

	function currency() external view returns (IERC20);

	function price() external view returns (uint256);

	function isWellFunded() external view returns (bool);

	function voteYes() external;

	function voteNo() external;
}

File 9 of 14 : IOfferFactory.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "../ERC20/IERC20.sol";
import "./IOffer.sol";

interface IOfferFactory {

	function create(
		bytes32 salt, address buyer, uint256 pricePerShare,	IERC20 currency,	uint256 quorum,	uint256 votePeriod
	) external payable returns (IOffer);
}

File 10 of 14 : ERC20Recoverable.sol
/**
* SPDX-License-Identifier: LicenseRef-Aktionariat
*
* MIT License with Automated License Fee Payments
*
* Copyright (c) 2022 Aktionariat AG (aktionariat.com)
*
* Permission is hereby granted to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* - The above copyright notice and this permission notice shall be included in
*   all copies or substantial portions of the Software.
* - All automated license fee payments integrated into this and related Software
*   are preserved.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
pragma solidity ^0.8.0;

import "../ERC20/ERC20Flaggable.sol";
import "./IRecoveryHub.sol";
import "./IRecoverable.sol";

/**
 * @title Recoverable
 * In case of tokens that represent real-world assets such as shares of a company, one needs a way
 * to handle lost private keys. With physical certificates, courts can declare share certificates as
 * invalid so the company can issue replacements. Here, we want a solution that does not depend on
 * third parties to resolve such cases. Instead, when someone has lost a private key, he can use the
 * declareLost function on the recovery hub to post a deposit and claim that the shares assigned to a
 * specific address are lost.
 * If an attacker trying to claim shares belonging to someone else, they risk losing the deposit
 * as it can be claimed at anytime by the rightful owner.
 * Furthermore, if "getClaimDeleter" is defined in the subclass, the returned address is allowed to
 * delete claims, returning the collateral. This can help to prevent obvious cases of abuse of the claim
 * function, e.g. cases of front-running.
 * Most functionality is implemented in a shared RecoveryHub.
 */
abstract contract ERC20Recoverable is ERC20Flaggable, IRecoverable {

    uint8 private constant FLAG_CLAIM_PRESENT = 10;

    // ERC-20 token that can be used as collateral or 0x0 if disabled
    IERC20 public customCollateralAddress;
    // Rate the custom collateral currency is multiplied to be valued like one share.
    uint256 public customCollateralRate;

    uint256 constant CLAIM_PERIOD = 180 days;

    IRecoveryHub public override immutable recovery;

    constructor(IRecoveryHub recoveryHub){
        recovery = recoveryHub;
    }

    /**
     * Returns the collateral rate for the given collateral type and 0 if that type
     * of collateral is not accepted. By default, only the token itself is accepted at
     * a rate of 1:1.
     *
     * Subclasses should override this method if they want to add additional types of
     * collateral.
     */
    function getCollateralRate(IERC20 collateralType) public override virtual view returns (uint256) {
        if (address(collateralType) == address(this)) {
            return 1;
        } else if (collateralType == customCollateralAddress) {
            return customCollateralRate;
        } else {
            return 0;
        }
    }

    function claimPeriod() external pure override returns (uint256){
        return CLAIM_PERIOD;
    }

    /**
     * Allows subclasses to set a custom collateral besides the token itself.
     * The collateral must be an ERC-20 token that returns true on successful transfers and
     * throws an exception or returns false on failure.
     * Also, do not forget to multiply the rate in accordance with the number of decimals of the collateral.
     * For example, rate should be 7*10**18 for 7 units of a collateral with 18 decimals.
     */
    function _setCustomClaimCollateral(IERC20 collateral, uint256 rate) internal {
        customCollateralAddress = collateral;
        if (address(customCollateralAddress) == address(0)) {
            customCollateralRate = 0; // disabled
        } else {
            require(rate > 0, "zero");
            customCollateralRate = rate;
        }
    }

    function getClaimDeleter() virtual public view returns (address);

    function transfer(address recipient, uint256 amount) override(ERC20Flaggable, IERC20) virtual public returns (bool) {
        require(super.transfer(recipient, amount), "transfer");
        if (hasFlagInternal(msg.sender, FLAG_CLAIM_PRESENT)){
            recovery.clearClaimFromToken(msg.sender);
        }
        return true;
    }

    function notifyClaimMade(address target) external override {
        require(msg.sender == address(recovery), "not recovery");
        setFlag(target, FLAG_CLAIM_PRESENT, true);
    }

    function notifyClaimDeleted(address target) external override {
        require(msg.sender == address(recovery), "not recovery");
        setFlag(target, FLAG_CLAIM_PRESENT, false);
    }

    function deleteClaim(address lostAddress) external {
        require(msg.sender == getClaimDeleter(), "not claim deleter");
        recovery.deleteClaim(lostAddress);
    }

    function recover(address oldAddress, address newAddress) external override {
        require(msg.sender == address(recovery), "not recovery");
        _transfer(oldAddress, newAddress, balanceOf(oldAddress));
    }

}

File 11 of 14 : IRecoverable.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "../ERC20/IERC20.sol";
import "./IRecoveryHub.sol";

interface IRecoverable is IERC20{

    // returns the recovery hub
    function recovery() external view returns (IRecoveryHub);

    function claimPeriod() external view returns (uint256);
    
    function notifyClaimMade(address target) external;

    function notifyClaimDeleted(address target) external;

    function getCollateralRate(IERC20 collateral) external view returns(uint256);

    function recover(address oldAddress, address newAddress) external;

}

File 12 of 14 : IRecoveryHub.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./IRecoverable.sol";

interface IRecoveryHub {

    function setRecoverable(bool flag) external;
    
    // deletes claim and transfers collateral back to claimer
    function deleteClaim(address target) external;

    // clears claim and transfers collateral to holder
    function clearClaimFromToken(address holder) external;

    function clearClaimFromUser(IRecoverable token) external;

}

File 13 of 14 : DraggableShares.sol
/**
* SPDX-License-Identifier: LicenseRef-Aktionariat
*
* MIT License with Automated License Fee Payments
*
* Copyright (c) 2022 Aktionariat AG (aktionariat.com)
*
* Permission is hereby granted to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* - The above copyright notice and this permission notice shall be included in
*   all copies or substantial portions of the Software.
* - All automated license fee payments integrated into this and related Software
*   are preserved.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
pragma solidity ^0.8.0;

import "../recovery/ERC20Recoverable.sol";
import "../draggable/ERC20Draggable.sol";
import "../ERC20/ERC20PermitLight.sol";

/**
 * @title CompanyName AG Shares SHA
 * @author Luzius Meisser, [email protected]
 *
 * This is an ERC-20 token representing share tokens of CompanyName AG that are bound to
 * a shareholder agreement that can be found at the URL defined in the constant 'terms'.
 */
contract DraggableShares is ERC20Draggable, ERC20Recoverable, ERC20PermitLight {

    string public terms;

    constructor(
        string memory _terms,
        IERC20 _wrappedToken,
        uint256 _quorumBps,
        uint256 _quorumMigration,
        uint256 _votePeriodSeconds,
        IRecoveryHub _recoveryHub,
        IOfferFactory _offerFactory,
        address _oracle
    )
        ERC20Draggable(_wrappedToken, _quorumBps, _quorumMigration, _votePeriodSeconds, _offerFactory, _oracle)
        ERC20Recoverable(_recoveryHub)
        ERC20PermitLight() 
    {
        terms = _terms; // to update the terms, migrate to a new contract. That way it is ensured that the terms can only be updated when the quorom agrees.
        _recoveryHub.setRecoverable(false);
    }

    function transfer(address to, uint256 value) virtual override(ERC20Flaggable, ERC20Recoverable) public returns (bool) {
        return super.transfer(to, value);
    }

    /**
     * Let the oracle act as deleter of invalid claims. In earlier versions, this was referring to the claim deleter
     * of the wrapped token. But that stops working after a successful acquisition as the acquisition currency most
     * likely does not have a claim deleter.
     */
    function getClaimDeleter() public view override returns (address) {
        return oracle;
    }

    function getCollateralRate(IERC20 collateralType) public view override returns (uint256) {
        uint256 rate = super.getCollateralRate(collateralType);
        if (rate > 0) {
            return rate;
        } else {
            // as long as it is binding, the conversion rate is 1:1
            uint256 factor = isBinding() ? 1 : unwrapConversionFactor;
            if (address(collateralType) == address(wrapped)) {
                // allow wrapped token as collateral
                return factor;
            } else {
                // If the wrapped contract allows for a specific collateral, we should too.
                // If the wrapped contract is not IRecoverable, we will fail here, but would fail anyway.
                return IRecoverable(address(wrapped)).getCollateralRate(collateralType) * factor;
            }
        }
    }

    function _beforeTokenTransfer(address from, address to, uint256 amount) virtual override(ERC20Flaggable, ERC20Draggable) internal {
        super._beforeTokenTransfer(from, to, amount);
    }

}

File 14 of 14 : IShares.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IShares {
	function burn(uint256) external;

	function totalShares() external view returns (uint256);
}

Settings
{
  "evmVersion": "london",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs",
    "useLiteralContent": true
  },
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "remappings": [],
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"_terms","type":"string"},{"internalType":"contract IERC20","name":"_wrappedToken","type":"address"},{"internalType":"uint256","name":"_quorumBps","type":"uint256"},{"internalType":"uint256","name":"_quorumMigration","type":"uint256"},{"internalType":"uint256","name":"_votePeriodSeconds","type":"uint256"},{"internalType":"contract IRecoveryHub","name":"_recoveryHub","type":"address"},{"internalType":"contract IOfferFactory","name":"_offerFactory","type":"address"},{"internalType":"address","name":"_oracle","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oracle","type":"address"}],"name":"ChangeOracle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newContractAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"yesVotes","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"oracleVotes","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalVotingPower","type":"uint256"}],"name":"MigrationSucceeded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"string","name":"symbol","type":"string"}],"name":"NameChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","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":"nonpayable","type":"function"},{"inputs":[],"name":"claimPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"customCollateralAddress","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"customCollateralRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"lostAddress","type":"address"}],"name":"deleteClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"buyer","type":"address"},{"internalType":"contract IERC20","name":"currency","type":"address"}],"name":"drag","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"contract IOfferFactory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getClaimDeleter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"collateralType","type":"address"}],"name":"getCollateralRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint8","name":"number","type":"uint8"}],"name":"hasFlag","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isBinding","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"uint256","name":"pricePerShare","type":"uint256"},{"internalType":"contract IERC20","name":"currency","type":"address"}],"name":"makeAcquisitionOffer","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"migrate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"successor","type":"address"},{"internalType":"uint256","name":"additionalVotes","type":"uint256"}],"name":"migrateWithExternalApproval","outputs":[],"stateMutability":"nonpayable","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":"target","type":"address"}],"name":"notifyClaimDeleted","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"notifyClaimMade","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"notifyOfferEnded","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"voter","type":"address"}],"name":"notifyVoted","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"offer","outputs":[{"internalType":"contract IOffer","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onTokenTransfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"oracle","outputs":[{"internalType":"address","name":"","type":"address"}],"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":"nonpayable","type":"function"},{"inputs":[],"name":"quorum","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"quorumMigration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"oldAddress","type":"address"},{"internalType":"address","name":"newAddress","type":"address"}],"name":"recover","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"recovery","outputs":[{"internalType":"contract IRecoveryHub","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOracle","type":"address"}],"name":"setOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"terms","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalVotingTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"transferAndCall","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"unwrap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unwrapConversionFactor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"votePeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"voter","type":"address"}],"name":"votingPower","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"shareholder","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"wrap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"wrapped","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

61012060405260006004553480156200001757600080fd5b5060405162002bcf38038062002bcf8339810160408190526200003a91620001e3565b600380546001600160a81b0319166101006001600160a01b038a811682029290921790925560c088905260a087905260e0869052606084811b6001600160601b0319908116608052600680546001600160a01b0319169386169390931790925585901b1690528751620000b590600a9060208b019062000120565b50604051636427ed9760e01b8152600060048201526001600160a01b03841690636427ed9790602401600060405180830381600087803b158015620000f957600080fd5b505af11580156200010e573d6000803e3d6000fd5b5050505050505050505050506200037c565b8280546200012e9062000329565b90600052602060002090601f0160209004810192826200015257600085556200019d565b82601f106200016d57805160ff19168380011785556200019d565b828001600101855582156200019d579182015b828111156200019d57825182559160200191906001019062000180565b50620001ab929150620001af565b5090565b5b80821115620001ab5760008155600101620001b0565b80516001600160a01b0381168114620001de57600080fd5b919050565b600080600080600080600080610100898b0312156200020157600080fd5b88516001600160401b03808211156200021957600080fd5b818b0191508b601f8301126200022e57600080fd5b81518181111562000243576200024362000366565b604051601f8201601f19908116603f011681019083821181831017156200026e576200026e62000366565b81604052828152602093508e848487010111156200028b57600080fd5b600091505b82821015620002af578482018401518183018501529083019062000290565b82821115620002c15760008484830101525b9b50620002d39150508b8201620001c6565b98505050604089015195506060890151945060808901519350620002fa60a08a01620001c6565b92506200030a60c08a01620001c6565b91506200031a60e08a01620001c6565b90509295985092959890939650565b600181811c908216806200033e57607f821691505b602082108114156200036057634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052604160045260246000fd5b60805160601c60a05160c05160e0516101005160601c6127c962000406600039600081816107fe01528181610bdd01528181610e17015281816111f7015281816116b80152611b60015260008181610668015261153801526000818161036b0152611512015260008181610872015261185c01526000818161073c015261156101526127c96000f3fe6080604052600436106102885760003560e01c80637dc0d1d01161015a578063c18172c4116100c1578063ddceafa91161007a578063ddceafa9146107ec578063de0e9a3e14610820578063e5b824ec14610840578063efa4051214610860578063f5c0b95f14610894578063fcb79a7e146108b457600080fd5b8063c18172c41461070a578063c45a01551461072a578063d50256251461075e578063d505accf14610773578063dcc7d4ad14610793578063dd62ed3e146107a657600080fd5b8063a4c0ed3611610113578063a4c0ed3614610636578063a781358714610656578063a9059cbb1461068a578063bf376c7a146106aa578063c028df06146106ca578063c07473f6146106ea57600080fd5b80637dc0d1d0146105935780637dc2cd98146105b35780637ecebe00146105c95780638fd3ab80146105f657806395d89b411461060b5780639e4b57451461062057600080fd5b806332a7ae95116101fe57806350e70d48116101b757806350e70d48146104d857806360918117146104fd578063648bf7741461051357806370a082311461053357806377e071ad146105535780637adbf9731461057357600080fd5b806332a7ae951461042e57806332bc320b1461044e5780633644e515146104635780634000aea01461047857806342966c681461049857806345c8a62b146104b857600080fd5b80631703a018116102505780631703a0181461035957806318160ddd1461038d57806319845354146103a257806323b872dd146103c45780632a0a4ed5146103e4578063313ce5671461040257600080fd5b806306fdde031461028d5780630832e470146102b8578063095ea7b3146102dc5780630a81b2de1461030c5780630c6f0e5d14610321575b600080fd5b34801561029957600080fd5b506102a26108d4565b6040516102af9190612598565b60405180910390f35b3480156102c457600080fd5b506102ce60045481565b6040519081526020016102af565b3480156102e857600080fd5b506102fc6102f7366004612268565b6109aa565b60405190151581526020016102af565b34801561031857600080fd5b506102ce6109c0565b34801561032d57600080fd5b50600754610341906001600160a01b031681565b6040516001600160a01b0390911681526020016102af565b34801561036557600080fd5b506102ce7f000000000000000000000000000000000000000000000000000000000000000081565b34801561039957600080fd5b506002546102ce565b3480156103ae57600080fd5b506103c26103bd366004612268565b610a4d565b005b3480156103d057600080fd5b506102fc6103df3660046121b9565b610af9565b3480156103f057600080fd5b506006546001600160a01b0316610341565b34801561040e57600080fd5b5060035461041c9060ff1681565b60405160ff90911681526020016102af565b34801561043a57600080fd5b506103c2610449366004612163565b610b70565b34801561045a57600080fd5b506103c2610c3d565b34801561046f57600080fd5b506102ce610c79565b34801561048457600080fd5b506102fc610493366004612294565b610cd2565b3480156104a457600080fd5b506103c26104b3366004612477565b610d72565b3480156104c457600080fd5b506103c26104d3366004612163565b610dd3565b3480156104e457600080fd5b506003546103419061010090046001600160a01b031681565b34801561050957600080fd5b506102ce60085481565b34801561051f57600080fd5b506103c261052e366004612180565b610e0c565b34801561053f57600080fd5b506102ce61054e366004612163565b610e67565b34801561055f57600080fd5b506102ce61056e366004612163565b610e8b565b34801561057f57600080fd5b506103c261058e366004612163565b610f7f565b34801561059f57600080fd5b50600654610341906001600160a01b031681565b3480156105bf57600080fd5b5062ed4e006102ce565b3480156105d557600080fd5b506102ce6105e4366004612163565b60096020526000908152604090205481565b34801561060257600080fd5b506103c261101b565b34801561061757600080fd5b506102a2611028565b34801561062c57600080fd5b50600454156102fc565b34801561064257600080fd5b506102fc610651366004612294565b6110d8565b34801561066257600080fd5b506102ce7f000000000000000000000000000000000000000000000000000000000000000081565b34801561069657600080fd5b506102fc6106a5366004612268565b611114565b3480156106b657600080fd5b506103c26106c5366004612268565b611127565b3480156106d657600080fd5b50600554610341906001600160a01b031681565b3480156106f657600080fd5b506102ce610705366004612163565b6111db565b34801561071657600080fd5b506103c2610725366004612163565b6111ec565b34801561073657600080fd5b506103417f000000000000000000000000000000000000000000000000000000000000000081565b34801561076a57600080fd5b506102a2611241565b34801561077f57600080fd5b506103c261078e3660046121fa565b6112cf565b6103c26107a1366004612374565b6114bf565b3480156107b257600080fd5b506102ce6107c1366004612180565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b3480156107f857600080fd5b506103417f000000000000000000000000000000000000000000000000000000000000000081565b34801561082c57600080fd5b506103c261083b366004612477565b611681565b34801561084c57600080fd5b506103c261085b366004612163565b6116ad565b34801561086c57600080fd5b506102ce7f000000000000000000000000000000000000000000000000000000000000000081565b3480156108a057600080fd5b506102fc6108af36600461231d565b611702565b3480156108c057600080fd5b506103c26108cf366004612180565b61170e565b60606000600360019054906101000a90046001600160a01b03166001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b15801561092657600080fd5b505afa15801561093a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261096291908101906123ca565b905061096e6004541590565b1561099957806040516020016109849190612503565b60405160208183030381529060405291505090565b8060405160200161098491906124d5565b60006109b7338484611756565b50600192915050565b6000600360019054906101000a90046001600160a01b03166001600160a01b0316633a98ef396040518163ffffffff1660e01b815260040160206040518083038186803b158015610a1057600080fd5b505afa158015610a24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a489190612490565b905090565b6006546001600160a01b03163314610a995760405162461bcd60e51b815260206004820152600a6024820152696e6f74206f7261636c6560b01b60448201526064015b60405180910390fd5b610aa16109c0565b81610aab60025490565b610ab59190612658565b1115610aeb5760405162461bcd60e51b8152602060048201526005602482015264766f74657360d81b6044820152606401610a90565b610af582826117b8565b5050565b6000610b06848484611925565b6001600160a01b0384166000908152600160209081526040808320338452909152902054600160ff1b811015610b6557610b4083826126d6565b6001600160a01b03861660009081526001602090815260408083203384529091529020555b506001949350505050565b6006546001600160a01b03163314610bbe5760405162461bcd60e51b81526020600482015260116024820152703737ba1031b630b4b6903232b632ba32b960791b6044820152606401610a90565b6040516332a7ae9560e01b81526001600160a01b0382811660048301527f000000000000000000000000000000000000000000000000000000000000000016906332a7ae95906024015b600060405180830381600087803b158015610c2257600080fd5b505af1158015610c36573d6000803e3d6000fd5b5050505050565b6005546001600160a01b03163314610c675760405162461bcd60e51b8152600401610a90906125f0565b600580546001600160a01b0319169055565b604080517f47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a794692186020820152469181019190915230606082015260009060800160405160208183030381529060405280519060200120905090565b6000610cde8585611114565b8015610d695750604051635260769b60e11b81526001600160a01b0386169063a4c0ed3690610d17903390889088908890600401612550565b602060405180830381600087803b158015610d3157600080fd5b505af1158015610d45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d699190612352565b95945050505050565b610d7c3382611989565b6003546001600160a01b03610100909104166342966c68610d9d6004541590565b610db357600454610dae90846126b7565b610db5565b825b6040518263ffffffff1660e01b8152600401610c0891815260200190565b6005546001600160a01b03163314610dfd5760405162461bcd60e51b8152600401610a90906125f0565b610e09816001806119fd565b50565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610e545760405162461bcd60e51b8152600401610a9090612632565b610af58282610e6285610e67565b611925565b6001600160a01b03166000908152602081905260409020546001600160e01b031690565b600080610e9783611a61565b90508015610ea55792915050565b6000610eb16004541590565b610ebd57600454610ec0565b60015b6003549091506001600160a01b03858116610100909204161415610ee5579392505050565b6003546040516377e071ad60e01b81526001600160a01b0386811660048301528392610100900416906377e071ad9060240160206040518083038186803b158015610f2f57600080fd5b505afa158015610f43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f679190612490565b610f7191906126b7565b949350505050565b50919050565b6006546001600160a01b03163314610fc65760405162461bcd60e51b815260206004820152600a6024820152696e6f74206f7261636c6560b01b6044820152606401610a90565b600680546001600160a01b0319166001600160a01b0383169081179091556040519081527fc3977c9522c218453912bcab15964a7788968fbf3fe4d4e2965252c9f07055de906020015b60405180910390a150565b6110263360006117b8565b565b6060600360019054906101000a90046001600160a01b03166001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b15801561107857600080fd5b505afa15801561108c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526110b491908101906123ca565b6040516020016110c4919061252b565b604051602081830303815290604052905090565b60035460009061010090046001600160a01b0316331461110a5760405162461bcd60e51b8152600401610a90906125f0565b610b658585611aa7565b60006111208383611b13565b9392505050565b6003546040516323b872dd60e01b8152336004820152306024820152604481018390526101009091046001600160a01b0316906323b872dd90606401602060405180830381600087803b15801561117d57600080fd5b505af1158015611191573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111b59190612352565b6111d15760405162461bcd60e51b8152600401610a9090612610565b610af58282611aa7565b60006111e682610e67565b92915050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146112345760405162461bcd60e51b8152600401610a9090612632565b610e0981600a60016119fd565b600a805461124e9061271d565b80601f016020809104026020016040519081016040528092919081815260200182805461127a9061271d565b80156112c75780601f1061129c576101008083540402835291602001916112c7565b820191906000526020600020905b8154815290600101906020018083116112aa57829003601f168201915b505050505081565b4284101561131f5760405162461bcd60e51b815260206004820152601760248201527f5045524d49545f444541444c494e455f455850495245440000000000000000006044820152606401610a90565b6000600161132b610c79565b6001600160a01b038a811660008181526009602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938d166060840152608083018c905260a083019390935260c08083018b90528151808403909101815260e08301909152805192019190912061190160f01b6101008301526101028201929092526101228101919091526101420160408051601f198184030181528282528051602091820120600084529083018083525260ff871690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015611437573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381161580159061146d5750876001600160a01b0316816001600160a01b0316145b6114aa5760405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa9a4a3a722a960911b6044820152606401610a90565b6114b5818888611756565b5050505050505050565b600454156114df5760405162461bcd60e51b8152600401610a90906125d0565b604051634dc5e43160e01b815260048101849052336024820152604481018390526001600160a01b0382811660648301527f000000000000000000000000000000000000000000000000000000000000000060848301527f000000000000000000000000000000000000000000000000000000000000000060a48301526000917f000000000000000000000000000000000000000000000000000000000000000090911690634dc5e43190349060c4016020604051808303818588803b1580156115a857600080fd5b505af11580156115bc573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906115e191906123ad565b90506115f76005546001600160a01b0316151590565b1561165c57600554604051637b64620f60e11b81526001600160a01b0383811660048301529091169063f6c8c41e90602401600060405180830381600087803b15801561164357600080fd5b505af1158015611657573d6000803e3d6000fd5b505050505b600580546001600160a01b0319166001600160a01b0392909216919091179055505050565b6004546116a05760405162461bcd60e51b8152600401610a90906125d0565b610e093382600454611bcd565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146116f55760405162461bcd60e51b8152600401610a9090612632565b610e0981600a60006119fd565b60006111208383611c97565b6005546001600160a01b031633146117385760405162461bcd60e51b8152600401610a90906125f0565b61174c8261174584610e67565b6001611bcd565b610af58183611cd7565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b60006117c383610e67565b6117cd9083612658565b905060006117d96109c0565b9050808211156118135760405162461bcd60e51b8152602060048201526005602482015264766f74657360d81b6044820152606401610a90565b6005546001600160a01b0316156118575760405162461bcd60e51b815260206004820152600860248201526737379037b33332b960c11b6044820152606401610a90565b6118817f0000000000000000000000000000000000000000000000000000000000000000826126b7565b61188d612710846126b7565b10156118c45760405162461bcd60e51b815260206004820152600660248201526571756f72756d60d01b6044820152606401610a90565b6118ce8485611cd7565b604080516001600160a01b038616815260208101849052908101849052606081018290527f85e5711a70a7d2bae18e1232af474d82c98600b0e62fe079a28208520b58568e9060800160405180910390a150505050565b611930838383611ec7565b61193a8382611ed2565b6119448282611f68565b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516117ab91815260200190565b61199582600083611ec7565b80600260008282546119a791906126d6565b909155506119b790508282611ed2565b6040518181526000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020015b60405180910390a35050565b6000611a0a8360e0612670565b6001600160a01b038516600090815260208190526040902054600160ff929092169190911b9150808216821483151514610c36576001600160a01b0394909416600090815260208190526040902093189092555050565b60006001600160a01b038216301415611a7c57506001919050565b6007546001600160a01b0383811691161415611a9a57505060085490565b506000919050565b919050565b611ab360008383611ec7565b8060026000828254611ac59190612658565b90915550611ad590508282611f68565b6040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020016119f1565b6000611b1f8383612018565b611b3b5760405162461bcd60e51b8152600401610a9090612610565b611b4633600a611c97565b156109b7576040516304d301a360e41b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690634d301a3090602401600060405180830381600087803b158015611bac57600080fd5b505af1158015611bc0573d6000803e3d6000fd5b5050505050600192915050565b611bd78383611989565b60035461010090046001600160a01b031663a9059cbb84611bf884866126b7565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b158015611c3e57600080fd5b505af1158015611c52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c769190612352565b611c925760405162461bcd60e51b8152600401610a9090612610565b505050565b600080611ca58360e0612670565b6001600160a01b038516600090815260208190526040902054600160ff929092169190911b9081161491505092915050565b60045415611cf75760405162461bcd60e51b8152600401610a90906125d0565b6003546040516370a0823160e01b81523060048201526101009091046001600160a01b03169063a9059cbb90839083906370a082319060240160206040518083038186803b158015611d4857600080fd5b505afa158015611d5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d809190612490565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b158015611dc657600080fd5b505af1158015611dda573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dfe9190612352565b611e1a5760405162461bcd60e51b8152600401610a9090612610565b60038054610100600160a81b0319166101006001600160a01b03851602179055600254610af5906040516370a0823160e01b81523060048201526001600160a01b038516906370a082319060240160206040518083038186803b158015611e8057600080fd5b505afa158015611e94573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eb89190612490565b611ec29190612695565b612025565b611c9283838361208a565b6001600160a01b03821660009081526020819052604081205490611ef683836126d6565b90506001600160e01b031981166001600160e01b0319831614611f475760405162461bcd60e51b8152602060048201526009602482015268756e646572666c6f7760b81b6044820152606401610a90565b6001600160a01b039093166000908152602081905260409020929092555050565b6001600160a01b038216611fa45760405162461bcd60e51b815260206004820152600360248201526203078360ec1b6044820152606401610a90565b6001600160a01b03821660009081526020819052604081205490611fc88383612658565b90506001600160e01b031981166001600160e01b0319831614611f475760405162461bcd60e51b81526020600482015260086024820152676f766572666c6f7760c01b6044820152606401610a90565b60006109b7338484611925565b60018110156120465760405162461bcd60e51b8152600401610a90906125d0565b60048190557f6c20b91d1723b78732eba64ff11ebd7966a6e4af568a00fa4f6b72c20f58b02a6120746108d4565b61207c611028565b6040516110109291906125ab565b61209383612145565b806120a257506120a282612145565b15611c92576005546001600160a01b03161561212b5760055460405163e1a1810f60e01b81526001600160a01b0385811660048301528481166024830152604482018490529091169063e1a1810f90606401600060405180830381600087803b15801561210e57600080fd5b505af1158015612122573d6000803e3d6000fd5b50505050505050565b61213883600160006119fd565b611c9282600160006119fd565b60006111e6826001611c97565b803560ff81168114611aa257600080fd5b60006020828403121561217557600080fd5b81356111208161277e565b6000806040838503121561219357600080fd5b823561219e8161277e565b915060208301356121ae8161277e565b809150509250929050565b6000806000606084860312156121ce57600080fd5b83356121d98161277e565b925060208401356121e98161277e565b929592945050506040919091013590565b600080600080600080600060e0888a03121561221557600080fd5b87356122208161277e565b965060208801356122308161277e565b9550604088013594506060880135935061224c60808901612152565b925060a0880135915060c0880135905092959891949750929550565b6000806040838503121561227b57600080fd5b82356122868161277e565b946020939093013593505050565b600080600080606085870312156122aa57600080fd5b84356122b58161277e565b935060208501359250604085013567ffffffffffffffff808211156122d957600080fd5b818701915087601f8301126122ed57600080fd5b8135818111156122fc57600080fd5b88602082850101111561230e57600080fd5b95989497505060200194505050565b6000806040838503121561233057600080fd5b823561233b8161277e565b915061234960208401612152565b90509250929050565b60006020828403121561236457600080fd5b8151801515811461112057600080fd5b60008060006060848603121561238957600080fd5b833592506020840135915060408401356123a28161277e565b809150509250925092565b6000602082840312156123bf57600080fd5b81516111208161277e565b6000602082840312156123dc57600080fd5b815167ffffffffffffffff808211156123f457600080fd5b818401915084601f83011261240857600080fd5b81518181111561241a5761241a612768565b604051601f8201601f19908116603f0116810190838211818310171561244257612442612768565b8160405282815287602084870101111561245b57600080fd5b61246c8360208301602088016126ed565b979650505050505050565b60006020828403121561248957600080fd5b5035919050565b6000602082840312156124a257600080fd5b5051919050565b600081518084526124c18160208601602086016126ed565b601f01601f19169290920160200192915050565b600082516124e78184602087016126ed565b692028577261707065642960b01b920191825250600a01919050565b600082516125158184602087016126ed565b632053484160e01b920191825250600401919050565b6000825161253d8184602087016126ed565b605360f81b920191825250600101919050565b6001600160a01b0385168152602081018490526060604082018190528101829052818360808301376000818301608090810191909152601f909201601f191601019392505050565b60208152600061112060208301846124a9565b6040815260006125be60408301856124a9565b8281036020840152610d6981856124a9565b6020808252600690820152653330b1ba37b960d11b604082015260600190565b60208082526006908201526539b2b73232b960d11b604082015260600190565b6020808252600890820152673a3930b739b332b960c11b604082015260600190565b6020808252600c908201526b6e6f74207265636f7665727960a01b604082015260600190565b6000821982111561266b5761266b612752565b500190565b600060ff821660ff84168060ff0382111561268d5761268d612752565b019392505050565b6000826126b257634e487b7160e01b600052601260045260246000fd5b500490565b60008160001904831182151516156126d1576126d1612752565b500290565b6000828210156126e8576126e8612752565b500390565b60005b838110156127085781810151838201526020016126f0565b83811115612717576000848401525b50505050565b600181811c9082168061273157607f821691505b60208210811415610f7957634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610e0957600080fdfea2646970667358221220bff69d37a3acfc072cdd9e25f4b91dd5ef638d6fa9f7b4d800be3daf71619ecc64736f6c634300080700330000000000000000000000000000000000000000000000000000000000000100000000000000000000000000765147bd2b25f6bb1e2bdcc1c06dd10ce7f3be4a000000000000000000000000000000000000000000000000000000000000196400000000000000000000000000000000000000000000000000000000000019640000000000000000000000000000000000000000000000000000000000278d00000000000000000000000000c6afd3b605957b9ba94143f59d451c657f5075160000000000000000000000001b8bf880e17fe5d8b2432a102346424b3237b2a70000000000000000000000006238cbb8e4190f3a744e5b9baa95f2dfceb7576f000000000000000000000000000000000000000000000000000000000000001b687474703a2f2f696e766573746f722e656c6c6578782e636f6d2f0000000000

Deployed Bytecode

0x6080604052600436106102885760003560e01c80637dc0d1d01161015a578063c18172c4116100c1578063ddceafa91161007a578063ddceafa9146107ec578063de0e9a3e14610820578063e5b824ec14610840578063efa4051214610860578063f5c0b95f14610894578063fcb79a7e146108b457600080fd5b8063c18172c41461070a578063c45a01551461072a578063d50256251461075e578063d505accf14610773578063dcc7d4ad14610793578063dd62ed3e146107a657600080fd5b8063a4c0ed3611610113578063a4c0ed3614610636578063a781358714610656578063a9059cbb1461068a578063bf376c7a146106aa578063c028df06146106ca578063c07473f6146106ea57600080fd5b80637dc0d1d0146105935780637dc2cd98146105b35780637ecebe00146105c95780638fd3ab80146105f657806395d89b411461060b5780639e4b57451461062057600080fd5b806332a7ae95116101fe57806350e70d48116101b757806350e70d48146104d857806360918117146104fd578063648bf7741461051357806370a082311461053357806377e071ad146105535780637adbf9731461057357600080fd5b806332a7ae951461042e57806332bc320b1461044e5780633644e515146104635780634000aea01461047857806342966c681461049857806345c8a62b146104b857600080fd5b80631703a018116102505780631703a0181461035957806318160ddd1461038d57806319845354146103a257806323b872dd146103c45780632a0a4ed5146103e4578063313ce5671461040257600080fd5b806306fdde031461028d5780630832e470146102b8578063095ea7b3146102dc5780630a81b2de1461030c5780630c6f0e5d14610321575b600080fd5b34801561029957600080fd5b506102a26108d4565b6040516102af9190612598565b60405180910390f35b3480156102c457600080fd5b506102ce60045481565b6040519081526020016102af565b3480156102e857600080fd5b506102fc6102f7366004612268565b6109aa565b60405190151581526020016102af565b34801561031857600080fd5b506102ce6109c0565b34801561032d57600080fd5b50600754610341906001600160a01b031681565b6040516001600160a01b0390911681526020016102af565b34801561036557600080fd5b506102ce7f000000000000000000000000000000000000000000000000000000000000196481565b34801561039957600080fd5b506002546102ce565b3480156103ae57600080fd5b506103c26103bd366004612268565b610a4d565b005b3480156103d057600080fd5b506102fc6103df3660046121b9565b610af9565b3480156103f057600080fd5b506006546001600160a01b0316610341565b34801561040e57600080fd5b5060035461041c9060ff1681565b60405160ff90911681526020016102af565b34801561043a57600080fd5b506103c2610449366004612163565b610b70565b34801561045a57600080fd5b506103c2610c3d565b34801561046f57600080fd5b506102ce610c79565b34801561048457600080fd5b506102fc610493366004612294565b610cd2565b3480156104a457600080fd5b506103c26104b3366004612477565b610d72565b3480156104c457600080fd5b506103c26104d3366004612163565b610dd3565b3480156104e457600080fd5b506003546103419061010090046001600160a01b031681565b34801561050957600080fd5b506102ce60085481565b34801561051f57600080fd5b506103c261052e366004612180565b610e0c565b34801561053f57600080fd5b506102ce61054e366004612163565b610e67565b34801561055f57600080fd5b506102ce61056e366004612163565b610e8b565b34801561057f57600080fd5b506103c261058e366004612163565b610f7f565b34801561059f57600080fd5b50600654610341906001600160a01b031681565b3480156105bf57600080fd5b5062ed4e006102ce565b3480156105d557600080fd5b506102ce6105e4366004612163565b60096020526000908152604090205481565b34801561060257600080fd5b506103c261101b565b34801561061757600080fd5b506102a2611028565b34801561062c57600080fd5b50600454156102fc565b34801561064257600080fd5b506102fc610651366004612294565b6110d8565b34801561066257600080fd5b506102ce7f0000000000000000000000000000000000000000000000000000000000278d0081565b34801561069657600080fd5b506102fc6106a5366004612268565b611114565b3480156106b657600080fd5b506103c26106c5366004612268565b611127565b3480156106d657600080fd5b50600554610341906001600160a01b031681565b3480156106f657600080fd5b506102ce610705366004612163565b6111db565b34801561071657600080fd5b506103c2610725366004612163565b6111ec565b34801561073657600080fd5b506103417f0000000000000000000000001b8bf880e17fe5d8b2432a102346424b3237b2a781565b34801561076a57600080fd5b506102a2611241565b34801561077f57600080fd5b506103c261078e3660046121fa565b6112cf565b6103c26107a1366004612374565b6114bf565b3480156107b257600080fd5b506102ce6107c1366004612180565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b3480156107f857600080fd5b506103417f000000000000000000000000c6afd3b605957b9ba94143f59d451c657f50751681565b34801561082c57600080fd5b506103c261083b366004612477565b611681565b34801561084c57600080fd5b506103c261085b366004612163565b6116ad565b34801561086c57600080fd5b506102ce7f000000000000000000000000000000000000000000000000000000000000196481565b3480156108a057600080fd5b506102fc6108af36600461231d565b611702565b3480156108c057600080fd5b506103c26108cf366004612180565b61170e565b60606000600360019054906101000a90046001600160a01b03166001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b15801561092657600080fd5b505afa15801561093a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261096291908101906123ca565b905061096e6004541590565b1561099957806040516020016109849190612503565b60405160208183030381529060405291505090565b8060405160200161098491906124d5565b60006109b7338484611756565b50600192915050565b6000600360019054906101000a90046001600160a01b03166001600160a01b0316633a98ef396040518163ffffffff1660e01b815260040160206040518083038186803b158015610a1057600080fd5b505afa158015610a24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a489190612490565b905090565b6006546001600160a01b03163314610a995760405162461bcd60e51b815260206004820152600a6024820152696e6f74206f7261636c6560b01b60448201526064015b60405180910390fd5b610aa16109c0565b81610aab60025490565b610ab59190612658565b1115610aeb5760405162461bcd60e51b8152602060048201526005602482015264766f74657360d81b6044820152606401610a90565b610af582826117b8565b5050565b6000610b06848484611925565b6001600160a01b0384166000908152600160209081526040808320338452909152902054600160ff1b811015610b6557610b4083826126d6565b6001600160a01b03861660009081526001602090815260408083203384529091529020555b506001949350505050565b6006546001600160a01b03163314610bbe5760405162461bcd60e51b81526020600482015260116024820152703737ba1031b630b4b6903232b632ba32b960791b6044820152606401610a90565b6040516332a7ae9560e01b81526001600160a01b0382811660048301527f000000000000000000000000c6afd3b605957b9ba94143f59d451c657f50751616906332a7ae95906024015b600060405180830381600087803b158015610c2257600080fd5b505af1158015610c36573d6000803e3d6000fd5b5050505050565b6005546001600160a01b03163314610c675760405162461bcd60e51b8152600401610a90906125f0565b600580546001600160a01b0319169055565b604080517f47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a794692186020820152469181019190915230606082015260009060800160405160208183030381529060405280519060200120905090565b6000610cde8585611114565b8015610d695750604051635260769b60e11b81526001600160a01b0386169063a4c0ed3690610d17903390889088908890600401612550565b602060405180830381600087803b158015610d3157600080fd5b505af1158015610d45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d699190612352565b95945050505050565b610d7c3382611989565b6003546001600160a01b03610100909104166342966c68610d9d6004541590565b610db357600454610dae90846126b7565b610db5565b825b6040518263ffffffff1660e01b8152600401610c0891815260200190565b6005546001600160a01b03163314610dfd5760405162461bcd60e51b8152600401610a90906125f0565b610e09816001806119fd565b50565b336001600160a01b037f000000000000000000000000c6afd3b605957b9ba94143f59d451c657f5075161614610e545760405162461bcd60e51b8152600401610a9090612632565b610af58282610e6285610e67565b611925565b6001600160a01b03166000908152602081905260409020546001600160e01b031690565b600080610e9783611a61565b90508015610ea55792915050565b6000610eb16004541590565b610ebd57600454610ec0565b60015b6003549091506001600160a01b03858116610100909204161415610ee5579392505050565b6003546040516377e071ad60e01b81526001600160a01b0386811660048301528392610100900416906377e071ad9060240160206040518083038186803b158015610f2f57600080fd5b505afa158015610f43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f679190612490565b610f7191906126b7565b949350505050565b50919050565b6006546001600160a01b03163314610fc65760405162461bcd60e51b815260206004820152600a6024820152696e6f74206f7261636c6560b01b6044820152606401610a90565b600680546001600160a01b0319166001600160a01b0383169081179091556040519081527fc3977c9522c218453912bcab15964a7788968fbf3fe4d4e2965252c9f07055de906020015b60405180910390a150565b6110263360006117b8565b565b6060600360019054906101000a90046001600160a01b03166001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b15801561107857600080fd5b505afa15801561108c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526110b491908101906123ca565b6040516020016110c4919061252b565b604051602081830303815290604052905090565b60035460009061010090046001600160a01b0316331461110a5760405162461bcd60e51b8152600401610a90906125f0565b610b658585611aa7565b60006111208383611b13565b9392505050565b6003546040516323b872dd60e01b8152336004820152306024820152604481018390526101009091046001600160a01b0316906323b872dd90606401602060405180830381600087803b15801561117d57600080fd5b505af1158015611191573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111b59190612352565b6111d15760405162461bcd60e51b8152600401610a9090612610565b610af58282611aa7565b60006111e682610e67565b92915050565b336001600160a01b037f000000000000000000000000c6afd3b605957b9ba94143f59d451c657f50751616146112345760405162461bcd60e51b8152600401610a9090612632565b610e0981600a60016119fd565b600a805461124e9061271d565b80601f016020809104026020016040519081016040528092919081815260200182805461127a9061271d565b80156112c75780601f1061129c576101008083540402835291602001916112c7565b820191906000526020600020905b8154815290600101906020018083116112aa57829003601f168201915b505050505081565b4284101561131f5760405162461bcd60e51b815260206004820152601760248201527f5045524d49545f444541444c494e455f455850495245440000000000000000006044820152606401610a90565b6000600161132b610c79565b6001600160a01b038a811660008181526009602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938d166060840152608083018c905260a083019390935260c08083018b90528151808403909101815260e08301909152805192019190912061190160f01b6101008301526101028201929092526101228101919091526101420160408051601f198184030181528282528051602091820120600084529083018083525260ff871690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015611437573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381161580159061146d5750876001600160a01b0316816001600160a01b0316145b6114aa5760405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa9a4a3a722a960911b6044820152606401610a90565b6114b5818888611756565b5050505050505050565b600454156114df5760405162461bcd60e51b8152600401610a90906125d0565b604051634dc5e43160e01b815260048101849052336024820152604481018390526001600160a01b0382811660648301527f000000000000000000000000000000000000000000000000000000000000196460848301527f0000000000000000000000000000000000000000000000000000000000278d0060a48301526000917f0000000000000000000000001b8bf880e17fe5d8b2432a102346424b3237b2a790911690634dc5e43190349060c4016020604051808303818588803b1580156115a857600080fd5b505af11580156115bc573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906115e191906123ad565b90506115f76005546001600160a01b0316151590565b1561165c57600554604051637b64620f60e11b81526001600160a01b0383811660048301529091169063f6c8c41e90602401600060405180830381600087803b15801561164357600080fd5b505af1158015611657573d6000803e3d6000fd5b505050505b600580546001600160a01b0319166001600160a01b0392909216919091179055505050565b6004546116a05760405162461bcd60e51b8152600401610a90906125d0565b610e093382600454611bcd565b336001600160a01b037f000000000000000000000000c6afd3b605957b9ba94143f59d451c657f50751616146116f55760405162461bcd60e51b8152600401610a9090612632565b610e0981600a60006119fd565b60006111208383611c97565b6005546001600160a01b031633146117385760405162461bcd60e51b8152600401610a90906125f0565b61174c8261174584610e67565b6001611bcd565b610af58183611cd7565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b60006117c383610e67565b6117cd9083612658565b905060006117d96109c0565b9050808211156118135760405162461bcd60e51b8152602060048201526005602482015264766f74657360d81b6044820152606401610a90565b6005546001600160a01b0316156118575760405162461bcd60e51b815260206004820152600860248201526737379037b33332b960c11b6044820152606401610a90565b6118817f0000000000000000000000000000000000000000000000000000000000001964826126b7565b61188d612710846126b7565b10156118c45760405162461bcd60e51b815260206004820152600660248201526571756f72756d60d01b6044820152606401610a90565b6118ce8485611cd7565b604080516001600160a01b038616815260208101849052908101849052606081018290527f85e5711a70a7d2bae18e1232af474d82c98600b0e62fe079a28208520b58568e9060800160405180910390a150505050565b611930838383611ec7565b61193a8382611ed2565b6119448282611f68565b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516117ab91815260200190565b61199582600083611ec7565b80600260008282546119a791906126d6565b909155506119b790508282611ed2565b6040518181526000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020015b60405180910390a35050565b6000611a0a8360e0612670565b6001600160a01b038516600090815260208190526040902054600160ff929092169190911b9150808216821483151514610c36576001600160a01b0394909416600090815260208190526040902093189092555050565b60006001600160a01b038216301415611a7c57506001919050565b6007546001600160a01b0383811691161415611a9a57505060085490565b506000919050565b919050565b611ab360008383611ec7565b8060026000828254611ac59190612658565b90915550611ad590508282611f68565b6040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020016119f1565b6000611b1f8383612018565b611b3b5760405162461bcd60e51b8152600401610a9090612610565b611b4633600a611c97565b156109b7576040516304d301a360e41b81523360048201527f000000000000000000000000c6afd3b605957b9ba94143f59d451c657f5075166001600160a01b031690634d301a3090602401600060405180830381600087803b158015611bac57600080fd5b505af1158015611bc0573d6000803e3d6000fd5b5050505050600192915050565b611bd78383611989565b60035461010090046001600160a01b031663a9059cbb84611bf884866126b7565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b158015611c3e57600080fd5b505af1158015611c52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c769190612352565b611c925760405162461bcd60e51b8152600401610a9090612610565b505050565b600080611ca58360e0612670565b6001600160a01b038516600090815260208190526040902054600160ff929092169190911b9081161491505092915050565b60045415611cf75760405162461bcd60e51b8152600401610a90906125d0565b6003546040516370a0823160e01b81523060048201526101009091046001600160a01b03169063a9059cbb90839083906370a082319060240160206040518083038186803b158015611d4857600080fd5b505afa158015611d5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d809190612490565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b158015611dc657600080fd5b505af1158015611dda573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dfe9190612352565b611e1a5760405162461bcd60e51b8152600401610a9090612610565b60038054610100600160a81b0319166101006001600160a01b03851602179055600254610af5906040516370a0823160e01b81523060048201526001600160a01b038516906370a082319060240160206040518083038186803b158015611e8057600080fd5b505afa158015611e94573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eb89190612490565b611ec29190612695565b612025565b611c9283838361208a565b6001600160a01b03821660009081526020819052604081205490611ef683836126d6565b90506001600160e01b031981166001600160e01b0319831614611f475760405162461bcd60e51b8152602060048201526009602482015268756e646572666c6f7760b81b6044820152606401610a90565b6001600160a01b039093166000908152602081905260409020929092555050565b6001600160a01b038216611fa45760405162461bcd60e51b815260206004820152600360248201526203078360ec1b6044820152606401610a90565b6001600160a01b03821660009081526020819052604081205490611fc88383612658565b90506001600160e01b031981166001600160e01b0319831614611f475760405162461bcd60e51b81526020600482015260086024820152676f766572666c6f7760c01b6044820152606401610a90565b60006109b7338484611925565b60018110156120465760405162461bcd60e51b8152600401610a90906125d0565b60048190557f6c20b91d1723b78732eba64ff11ebd7966a6e4af568a00fa4f6b72c20f58b02a6120746108d4565b61207c611028565b6040516110109291906125ab565b61209383612145565b806120a257506120a282612145565b15611c92576005546001600160a01b03161561212b5760055460405163e1a1810f60e01b81526001600160a01b0385811660048301528481166024830152604482018490529091169063e1a1810f90606401600060405180830381600087803b15801561210e57600080fd5b505af1158015612122573d6000803e3d6000fd5b50505050505050565b61213883600160006119fd565b611c9282600160006119fd565b60006111e6826001611c97565b803560ff81168114611aa257600080fd5b60006020828403121561217557600080fd5b81356111208161277e565b6000806040838503121561219357600080fd5b823561219e8161277e565b915060208301356121ae8161277e565b809150509250929050565b6000806000606084860312156121ce57600080fd5b83356121d98161277e565b925060208401356121e98161277e565b929592945050506040919091013590565b600080600080600080600060e0888a03121561221557600080fd5b87356122208161277e565b965060208801356122308161277e565b9550604088013594506060880135935061224c60808901612152565b925060a0880135915060c0880135905092959891949750929550565b6000806040838503121561227b57600080fd5b82356122868161277e565b946020939093013593505050565b600080600080606085870312156122aa57600080fd5b84356122b58161277e565b935060208501359250604085013567ffffffffffffffff808211156122d957600080fd5b818701915087601f8301126122ed57600080fd5b8135818111156122fc57600080fd5b88602082850101111561230e57600080fd5b95989497505060200194505050565b6000806040838503121561233057600080fd5b823561233b8161277e565b915061234960208401612152565b90509250929050565b60006020828403121561236457600080fd5b8151801515811461112057600080fd5b60008060006060848603121561238957600080fd5b833592506020840135915060408401356123a28161277e565b809150509250925092565b6000602082840312156123bf57600080fd5b81516111208161277e565b6000602082840312156123dc57600080fd5b815167ffffffffffffffff808211156123f457600080fd5b818401915084601f83011261240857600080fd5b81518181111561241a5761241a612768565b604051601f8201601f19908116603f0116810190838211818310171561244257612442612768565b8160405282815287602084870101111561245b57600080fd5b61246c8360208301602088016126ed565b979650505050505050565b60006020828403121561248957600080fd5b5035919050565b6000602082840312156124a257600080fd5b5051919050565b600081518084526124c18160208601602086016126ed565b601f01601f19169290920160200192915050565b600082516124e78184602087016126ed565b692028577261707065642960b01b920191825250600a01919050565b600082516125158184602087016126ed565b632053484160e01b920191825250600401919050565b6000825161253d8184602087016126ed565b605360f81b920191825250600101919050565b6001600160a01b0385168152602081018490526060604082018190528101829052818360808301376000818301608090810191909152601f909201601f191601019392505050565b60208152600061112060208301846124a9565b6040815260006125be60408301856124a9565b8281036020840152610d6981856124a9565b6020808252600690820152653330b1ba37b960d11b604082015260600190565b60208082526006908201526539b2b73232b960d11b604082015260600190565b6020808252600890820152673a3930b739b332b960c11b604082015260600190565b6020808252600c908201526b6e6f74207265636f7665727960a01b604082015260600190565b6000821982111561266b5761266b612752565b500190565b600060ff821660ff84168060ff0382111561268d5761268d612752565b019392505050565b6000826126b257634e487b7160e01b600052601260045260246000fd5b500490565b60008160001904831182151516156126d1576126d1612752565b500290565b6000828210156126e8576126e8612752565b500390565b60005b838110156127085781810151838201526020016126f0565b83811115612717576000848401525b50505050565b600181811c9082168061273157607f821691505b60208210811415610f7957634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610e0957600080fdfea2646970667358221220bff69d37a3acfc072cdd9e25f4b91dd5ef638d6fa9f7b4d800be3daf71619ecc64736f6c63430008070033

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.