EthereumEthereum
0xa4...ea5e
Cornichon

Cornichon

CORN

代币
市值
$1.00
 
价格
2%
此合同的源代码已经过验证!
合同元数据
编译器
0.2.7+commit.0b3f3b3
语言
Vyper
合同源代码
文件 1 的 1:Vyper_contract.vy
# @version 0.2.7
from vyper.interfaces import ERC20

implements: ERC20

event Transfer:
    sender: indexed(address)
    receiver: indexed(address)
    value: uint256

event Approval:
    owner: indexed(address)
    spender: indexed(address)
    value: uint256

event Pickled:
    receiver: indexed(address)
    corn: uint256
    dai: uint256

struct Permit:
    owner: address
    spender: address
    amount: uint256
    nonce: uint256
    expiry: uint256


name: public(String[64])
symbol: public(String[32])
decimals: public(uint256)
balanceOf: public(HashMap[address, uint256])
nonces: public(HashMap[address, uint256])
allowances: HashMap[address, HashMap[address, uint256]]
total_supply: uint256
dai: ERC20
DOMAIN_SEPARATOR: public(bytes32)
contract_version: constant(String[32]) = "1"
DOMAIN_TYPE_HASH: constant(bytes32) = keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)')
PERMIT_TYPE_HASH: constant(bytes32) = keccak256("Permit(address owner,address spender,uint256 amount,uint256 nonce,uint256 expiry)")


@external
def __init__(_name: String[64], _symbol: String[32], _supply: uint256):
    self.name = _name
    self.symbol = _symbol
    self.decimals = 18
    self.dai = ERC20(0x6B175474E89094C44Da98b954EedeAC495271d0F)
    self.balanceOf[msg.sender] = _supply
    self.total_supply = _supply
    log Transfer(ZERO_ADDRESS, msg.sender, _supply)

    self.DOMAIN_SEPARATOR = keccak256(
        concat(
            DOMAIN_TYPE_HASH,
            keccak256(convert(self.name, Bytes[64])),
            keccak256(convert(contract_version, Bytes[32])),
            convert(chain.id, bytes32),
            convert(self, bytes32)
        )
    )


@view
@external
def totalSupply() -> uint256:
    return self.total_supply


@view
@external
def version() -> String[32]:
    return contract_version


@view
@external
def allowance(owner: address, spender: address) -> uint256:
    return self.allowances[owner][spender]


@internal
def _transfer(sender: address, source: address, receiver: address, amount: uint256) -> bool:
    assert not receiver in [self, ZERO_ADDRESS]
    self.balanceOf[source] -= amount
    self.balanceOf[receiver] += amount
    if source != sender and self.allowances[source][sender] != MAX_UINT256:
        self.allowances[source][sender] -= amount
        log Approval(source, sender, amount)
    log Transfer(source, receiver, amount)
    return True


@external
def transfer(receiver: address, amount: uint256) -> bool:
    return self._transfer(msg.sender, msg.sender, receiver, amount)


@external
def transferFrom(source: address, receiver: address, amount: uint256) -> bool:
    return self._transfer(msg.sender, source, receiver, amount)


@external
def approve(spender: address, amount: uint256) -> bool:
    self.allowances[msg.sender][spender] = amount
    log Approval(msg.sender, spender, amount)
    return True


@view
@internal
def _rate(amount: uint256) -> uint256:
    if self.total_supply == 0:
        return 0
    return amount * self.dai.balanceOf(self) / self.total_supply


@view
@external
def rate() -> uint256:
    return self._rate(10 ** self.decimals)


@internal
def _burn(sender: address, source: address, amount: uint256):
    assert source != ZERO_ADDRESS
    redeemed: uint256 = self._rate(amount)
    self.dai.transfer(source, redeemed)
    log Pickled(source, amount, redeemed)
    self.total_supply -= amount
    self.balanceOf[source] -= amount
    if source != sender and self.allowances[source][sender] != MAX_UINT256:
        self.allowances[source][sender] -= amount
        log Approval(source, sender, amount)
    log Transfer(source, ZERO_ADDRESS, amount)


@external
def burn(_amount: uint256 = MAX_UINT256):
    """
    Burn CORN for DAI at a rate of (DAI in contract / CORN supply)
    """
    amount: uint256 = min(_amount, self.balanceOf[msg.sender])
    self._burn(msg.sender, msg.sender, amount)


@external
def burnFrom(source: address, amount: uint256):
    self._burn(msg.sender, source, amount)


@view
@internal
def message_digest(owner: address, spender: address, amount: uint256, nonce: uint256, expiry: uint256) -> bytes32:
    return keccak256(
        concat(
            b'\x19\x01',
            self.DOMAIN_SEPARATOR,
            keccak256(
                concat(
                    PERMIT_TYPE_HASH,
                    convert(owner, bytes32),
                    convert(spender, bytes32),
                    convert(amount, bytes32),
                    convert(nonce, bytes32),
                    convert(expiry, bytes32),
                )
            )
        )
    )


@external
def permit(owner: address, spender: address, amount: uint256, nonce: uint256, expiry: uint256, signature: Bytes[65]) -> bool:
    assert expiry >= block.timestamp  # dev: permit expired
    assert owner != ZERO_ADDRESS  # dev: invalid owner
    assert nonce == self.nonces[owner]  # dev: invalid nonce
    digest: bytes32 = self.message_digest(owner, spender, amount, nonce, expiry)
    # NOTE: signature is packed as r, s, v
    r: uint256 = convert(slice(signature, 0, 32), uint256)
    s: uint256 = convert(slice(signature, 32, 32), uint256)
    v: uint256 = convert(slice(signature, 64, 1), uint256)
    assert ecrecover(digest, v, r, s) == owner  # dev: invalid signature

    self.allowances[owner][spender] = amount
    self.nonces[owner] += 1
    log Approval(owner, spender, amount)
    return True
设置
{
  "compilationTarget": {
    "Vyper_contract.vy": "Vyper_contract"
  },
  "outputSelection": {
    "Vyper_contract.vy": [
      "abi",
      "ast",
      "interface",
      "ir",
      "userdoc",
      "devdoc",
      "evm.bytecode.object",
      "evm.bytecode.opcodes",
      "evm.deployedBytecode.object",
      "evm.deployedBytecode.opcodes",
      "evm.deployedBytecode.sourceMap",
      "evm.methodIdentifiers"
    ]
  },
  "search_paths": [
    "."
  ]
}
ABI
[{"anonymous":false,"inputs":[{"indexed":true,"name":"sender","type":"address"},{"indexed":true,"name":"receiver","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"receiver","type":"address"},{"indexed":false,"name":"corn","type":"uint256"},{"indexed":false,"name":"dai","type":"uint256"}],"name":"Pickled","type":"event"},{"inputs":[{"name":"_name","type":"string"},{"name":"_symbol","type":"string"},{"name":"_supply","type":"uint256"}],"outputs":[],"stateMutability":"nonpayable","type":"constructor"},{"gas":1061,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"gas":4519,"inputs":[],"name":"version","outputs":[{"name":"","type":"string"}],"stateMutability":"view","type":"function"},{"gas":1551,"inputs":[{"name":"owner","type":"address"},{"name":"spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"gas":115661,"inputs":[{"name":"receiver","type":"address"},{"name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"gas":115795,"inputs":[{"name":"source","type":"address"},{"name":"receiver","type":"address"},{"name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"gas":37884,"inputs":[{"name":"spender","type":"address"},{"name":"amount","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"gas":6113,"inputs":[],"name":"rate","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"gas":127210,"inputs":[{"name":"source","type":"address"},{"name":"amount","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"gas":83136,"inputs":[{"name":"owner","type":"address"},{"name":"spender","type":"address"},{"name":"amount","type":"uint256"},{"name":"nonce","type":"uint256"},{"name":"expiry","type":"uint256"},{"name":"signature","type":"bytes"}],"name":"permit","outputs":[{"name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"gas":7883,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"stateMutability":"view","type":"function"},{"gas":6936,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"stateMutability":"view","type":"function"},{"gas":1541,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"gas":1786,"inputs":[{"name":"arg0","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"gas":1816,"inputs":[{"name":"arg0","type":"address"}],"name":"nonces","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"gas":1631,"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"name":"","type":"bytes32"}],"stateMutability":"view","type":"function"}]