Address Details
contract

0xf5592321D362282a854CA702Eb382F334552AEcf

Contract Name
PlastikBurner
Creator
0xbeeb49–5df762 at 0x601fbe–c18ec4
Balance
0 CELO ( )
Locked CELO Balance
0.00 CELO
Voting CELO Balance
0.00 CELO
Pending Unlocked Gold
0.00 CELO
Tokens
Fetching tokens...
Transactions
0 Transactions
Transfers
627 Transfers
Gas Used
Fetching gas used...
Last Balance Update
24265715
This contract has been verified via Sourcify. View contract in Sourcify repository
Contract name:
PlastikBurner




Optimization enabled
false
Compiler version
v0.8.9+commit.e5eed63a




EVM Version
london




Verified at
2023-05-24T14:54:25.377698Z

contracts/PlastikBurner.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import "@openzeppelin/contracts/access/Ownable.sol";
import "./PlastikToken.sol";


// 35714285714285714 = MAX Burn per year =   ((Total PLASTIK supply) / (Years to meet plastic neutrallity))
// 1Kg PRG burns =   ((Total PLASTIK supply) / (Years to meet plastic neutrallity)) / (Yearly Plastic production in KG) PLASTIK
// Total PLASTIK supply = 1.000.000.000 PLASTIK
// Years to meet plastic neutrallity = 28
// MAX Burn per year = 35.714.285 PLASTIK
// Yearly Plastic production in KG = (will vary every year, but for now) 300.000.000.000 KG
// 1KG PRG burns (until MAX Burn per year is achieve) -> 0.000119047 PLASTIK (edited) 

contract PlastikBurner is Ownable {

    PlastikToken plastikToken;

    uint96 year = 2023;

    uint256 maxBurnYear = 35714285714285714;
    uint256 plasticProduction = 300000000000;  // 300 bil
    uint256 burnPerKg = 119047; // 0.000119047 PLASTIK per Kg

    event PlastikBurned(address indexed sender, uint256 quantity, uint96 indexed year);

    constructor(address plastikTokenAddress, uint96 _year, uint256 _plasticProduction, uint256 _maxBurnYear) {
        plastikToken = PlastikToken(plastikTokenAddress);
        year = _year;
        plasticProduction = _plasticProduction;
        require(_plasticProduction > 0, "plasticProduction must be bigger than 0");
        require(_maxBurnYear > 0, "maxBurnYear must be bigger than 0");
        maxBurnYear = _maxBurnYear;
        burnPerKg = _maxBurnYear / _plasticProduction;
    }

    //Burn Rate per Kg
    function currentBurnRate() public view returns (uint256) {
        uint256 balance = plastikToken.balanceOf(address(this));
        if(balance < maxBurnYear) {
            return burnPerKg;
        }
        return 0;
    }

    function getBalance() external view returns (uint256){
        return plastikToken.balanceOf(address(this));
    }

    function setPlasticProduction(uint256 quantity) onlyOwner public returns (bool) {
        require(quantity > 0, "plasticProduction must be bigger than 0");
        plasticProduction = quantity;
        burnPerKg = maxBurnYear / plasticProduction;
        return true;
    }

    function setMaxBurnYear(uint256 quantity) onlyOwner public returns (bool) {
        require(quantity > 0, "maxBurnYear must be bigger than 0");
        maxBurnYear = quantity;
        burnPerKg = maxBurnYear / plasticProduction;
        return true;
    }

}
        

/_openzeppelin/contracts/access/Ownable.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}
          

/_openzeppelin/contracts/security/Pausable.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract Pausable is Context {
    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state.
     */
    constructor() {
        _paused = false;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        _requireNotPaused();
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused() {
        _requirePaused();
        _;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view virtual returns (bool) {
        return _paused;
    }

    /**
     * @dev Throws if the contract is paused.
     */
    function _requireNotPaused() internal view virtual {
        require(!paused(), "Pausable: paused");
    }

    /**
     * @dev Throws if the contract is not paused.
     */
    function _requirePaused() internal view virtual {
        require(paused(), "Pausable: not paused");
    }

    /**
     * @dev Triggers stopped state.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    function _pause() internal virtual whenNotPaused {
        _paused = true;
        emit Paused(_msgSender());
    }

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause() internal virtual whenPaused {
        _paused = false;
        emit Unpaused(_msgSender());
    }
}
          

/_openzeppelin/contracts/token/ERC20/ERC20.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)

pragma solidity ^0.8.0;

import "./IERC20.sol";
import "./extensions/IERC20Metadata.sol";
import "../../utils/Context.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 {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead 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}.
 */
contract ERC20 is Context, IERC20, IERC20Metadata {
    mapping(address => uint256) private _balances;

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

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * The default value of {decimals} is 18. To select a different value for
     * {decimals} you should overload it.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5.05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless this function is
     * overridden;
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual override returns (uint8) {
        return 18;
    }

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

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

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

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

    /**
     * @dev See {IERC20-approve}.
     *
     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
     * `transferFrom`. This is semantically equivalent to an infinite approval.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, amount);
        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}.
     *
     * NOTE: Does not update the allowance if the current allowance
     * is the maximum `uint256`.
     *
     * Requirements:
     *
     * - `from` and `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     * - the caller must have allowance for ``from``'s tokens of at least
     * `amount`.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual override returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, amount);
        _transfer(from, to, amount);
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, allowance(owner, spender) + addedValue);
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        address owner = _msgSender();
        uint256 currentAllowance = allowance(owner, spender);
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(owner, spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    /**
     * @dev Moves `amount` of tokens from `from` to `to`.
     *
     * This 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:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     */
    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(from, to, amount);

        uint256 fromBalance = _balances[from];
        require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[from] = fromBalance - amount;
        }
        _balances[to] += amount;

        emit Transfer(from, to, amount);

        _afterTokenTransfer(from, to, amount);
    }

    /** @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:
     *
     * - `account` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply += amount;
        _balances[account] += amount;
        emit Transfer(address(0), account, amount);

        _afterTokenTransfer(address(0), account, amount);
    }

    /**
     * @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 {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        unchecked {
            _balances[account] = accountBalance - amount;
        }
        _totalSupply -= amount;

        emit Transfer(account, address(0), amount);

        _afterTokenTransfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This 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 amount
    ) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Updates `owner` s allowance for `spender` based on spent `amount`.
     *
     * Does not update the allowance amount in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Might emit an {Approval} event.
     */
    function _spendAllowance(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            require(currentAllowance >= amount, "ERC20: insufficient allowance");
            unchecked {
                _approve(owner, spender, currentAllowance - amount);
            }
        }
    }

    /**
     * @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 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].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * has been transferred to `to`.
     * - when `from` is zero, `amount` tokens have been minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}
}
          

/_openzeppelin/contracts/token/ERC20/IERC20.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @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);

    /**
     * @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 `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, 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.
     *
     * IMPORTANT: 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 `from` to `to` 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 from,
        address to,
        uint256 amount
    ) external returns (bool);
}
          

/_openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Pausable.sol)

pragma solidity ^0.8.0;

import "../ERC20.sol";
import "../../../security/Pausable.sol";

/**
 * @dev ERC20 token with pausable token transfers, minting and burning.
 *
 * Useful for scenarios such as preventing trades until the end of an evaluation
 * period, or having an emergency switch for freezing all token transfers in the
 * event of a large bug.
 */
abstract contract ERC20Pausable is ERC20, Pausable {
    /**
     * @dev See {ERC20-_beforeTokenTransfer}.
     *
     * Requirements:
     *
     * - the contract must not be paused.
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual override {
        super._beforeTokenTransfer(from, to, amount);

        require(!paused(), "ERC20Pausable: token transfer while paused");
    }
}
          

/_openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.0;

import "../IERC20.sol";

/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}
          

/_openzeppelin/contracts/utils/Context.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}
          

/contracts/PlastikToken.sol

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol";


contract PlastikToken is ERC20, ERC20Pausable {
    
    address private _owner;
    mapping(address => bool) private _lockers;
    mapping(address => uint256) private _locks;
    
    constructor() ERC20("PLASTIK Token", "PLASTIK") {
        _owner = _msgSender();
        _lockers[_msgSender()] = true;
        _mint(_msgSender(), 1000000000 * (10 ** decimals()));
    }

    modifier onlyOwner {
      require(msg.sender == _owner);
      _;
    }

    function pause() public virtual onlyOwner {
        _pause();
    }

    function unpause() public virtual onlyOwner {
        _unpause();
    }
    
    function decimals() public view virtual override(ERC20) returns (uint8) {
        return 9;
    }
    
    function setLocker(address locker, bool canLock) public virtual onlyOwner {
        _lockers[locker] = canLock;
    }
    
    function getLockupTime(address _address) public view virtual returns (uint256) {
        return _locks[_address];
    }

    function transferWithLockup(address recipient, uint256 amount, uint numMonthsLockup) public virtual returns (bool) {
        require(numMonthsLockup > 0 && numMonthsLockup <= 12, "Lockup cannot be smaller than 0 or greater than 12 months");
        require(_lockers[_msgSender()], "Only lockers can lock");
        uint256 previousBalance = balanceOf(recipient);
        transfer(recipient, amount);
        if(_locks[recipient] == 0 && previousBalance == 0) {
            _locks[recipient] = block.timestamp + (numMonthsLockup * 4 weeks );
        }
        return true;
    }

    function transferFromWithLockup(address sender, address recipient, uint256 amount, uint numMonthsLockup) public virtual returns (bool) {
        require(numMonthsLockup > 0 && numMonthsLockup <= 12, "Lockup cannot be smaller than 0 or greater than 12 months");
        require(_lockers[_msgSender()], "Only lockers can lock");
        uint256 previousBalance = balanceOf(recipient);
        transferFrom(sender, recipient, amount);
        if(_locks[recipient] == 0 && previousBalance == 0) {
            _locks[recipient] = block.timestamp + (numMonthsLockup * 4 weeks );
        }
        return true;
    }
    
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual override(ERC20, ERC20Pausable) {
        require(_owner == from || _locks[from] == 0 || _locks[from] <= block.timestamp, "Wallet is locked");
        super._beforeTokenTransfer(from, to, amount);
    }
}
          

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"plastikTokenAddress","internalType":"address"},{"type":"uint96","name":"_year","internalType":"uint96"},{"type":"uint256","name":"_plasticProduction","internalType":"uint256"},{"type":"uint256","name":"_maxBurnYear","internalType":"uint256"}]},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"PlastikBurned","inputs":[{"type":"address","name":"sender","internalType":"address","indexed":true},{"type":"uint256","name":"quantity","internalType":"uint256","indexed":false},{"type":"uint96","name":"year","internalType":"uint96","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"currentBurnRate","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getBalance","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"setMaxBurnYear","inputs":[{"type":"uint256","name":"quantity","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"setPlasticProduction","inputs":[{"type":"uint256","name":"quantity","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]}]
              

Contract Creation Code

0x60806040526107e7600160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550667ee1f4216824926002556445d964b8006003556201d1076004553480156200005f57600080fd5b506040516200100e3803806200100e833981810160405281019062000085919062000389565b620000a562000099620001cf60201b60201c565b620001d760201b60201c565b83600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550816003819055506000821162000164576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200015b9062000482565b60405180910390fd5b60008111620001aa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620001a1906200051a565b60405180910390fd5b806002819055508181620001bf91906200056b565b60048190555050505050620005a3565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620002cd82620002a0565b9050919050565b620002df81620002c0565b8114620002eb57600080fd5b50565b600081519050620002ff81620002d4565b92915050565b60006bffffffffffffffffffffffff82169050919050565b620003288162000305565b81146200033457600080fd5b50565b60008151905062000348816200031d565b92915050565b6000819050919050565b62000363816200034e565b81146200036f57600080fd5b50565b600081519050620003838162000358565b92915050565b60008060008060808587031215620003a657620003a56200029b565b5b6000620003b687828801620002ee565b9450506020620003c98782880162000337565b9350506040620003dc8782880162000372565b9250506060620003ef8782880162000372565b91505092959194509250565b600082825260208201905092915050565b7f706c617374696350726f64756374696f6e206d7573742062652062696767657260008201527f207468616e203000000000000000000000000000000000000000000000000000602082015250565b60006200046a602783620003fb565b915062000477826200040c565b604082019050919050565b600060208201905081810360008301526200049d816200045b565b9050919050565b7f6d61784275726e59656172206d75737420626520626967676572207468616e2060008201527f3000000000000000000000000000000000000000000000000000000000000000602082015250565b600062000502602183620003fb565b91506200050f82620004a4565b604082019050919050565b600060208201905081810360008301526200053581620004f3565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600062000578826200034e565b915062000585836200034e565b9250826200059857620005976200053c565b5b828204905092915050565b610a5b80620005b36000396000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c80638f7807311161005b5780638f780731146100c8578063ae6180c2146100f8578063d66cc15314610116578063f2fde38b146101465761007d565b806312065fe014610082578063715018a6146100a05780638da5cb5b146100aa575b600080fd5b61008a610162565b60405161009791906105ec565b60405180910390f35b6100a8610214565b005b6100b2610228565b6040516100bf9190610648565b60405180910390f35b6100e260048036038101906100dd9190610694565b610251565b6040516100ef91906106dc565b60405180910390f35b6101006102c4565b60405161010d91906105ec565b60405180910390f35b610130600480360381019061012b9190610694565b610392565b60405161013d91906106dc565b60405180910390f35b610160600480360381019061015b9190610723565b610405565b005b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016101bf9190610648565b60206040518083038186803b1580156101d757600080fd5b505afa1580156101eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061020f9190610765565b905090565b61021c610489565b6102266000610507565b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600061025b610489565b6000821161029e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161029590610815565b60405180910390fd5b816003819055506003546002546102b59190610864565b60048190555060019050919050565b600080600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016103229190610648565b60206040518083038186803b15801561033a57600080fd5b505afa15801561034e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103729190610765565b90506002548110156103895760045491505061038f565b60009150505b90565b600061039c610489565b600082116103df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103d690610907565b60405180910390fd5b816002819055506003546002546103f69190610864565b60048190555060019050919050565b61040d610489565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561047d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161047490610999565b60405180910390fd5b61048681610507565b50565b6104916105cb565b73ffffffffffffffffffffffffffffffffffffffff166104af610228565b73ffffffffffffffffffffffffffffffffffffffff1614610505576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104fc90610a05565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b6000819050919050565b6105e6816105d3565b82525050565b600060208201905061060160008301846105dd565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061063282610607565b9050919050565b61064281610627565b82525050565b600060208201905061065d6000830184610639565b92915050565b600080fd5b610671816105d3565b811461067c57600080fd5b50565b60008135905061068e81610668565b92915050565b6000602082840312156106aa576106a9610663565b5b60006106b88482850161067f565b91505092915050565b60008115159050919050565b6106d6816106c1565b82525050565b60006020820190506106f160008301846106cd565b92915050565b61070081610627565b811461070b57600080fd5b50565b60008135905061071d816106f7565b92915050565b60006020828403121561073957610738610663565b5b60006107478482850161070e565b91505092915050565b60008151905061075f81610668565b92915050565b60006020828403121561077b5761077a610663565b5b600061078984828501610750565b91505092915050565b600082825260208201905092915050565b7f706c617374696350726f64756374696f6e206d7573742062652062696767657260008201527f207468616e203000000000000000000000000000000000000000000000000000602082015250565b60006107ff602783610792565b915061080a826107a3565b604082019050919050565b6000602082019050818103600083015261082e816107f2565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061086f826105d3565b915061087a836105d3565b92508261088a57610889610835565b5b828204905092915050565b7f6d61784275726e59656172206d75737420626520626967676572207468616e2060008201527f3000000000000000000000000000000000000000000000000000000000000000602082015250565b60006108f1602183610792565b91506108fc82610895565b604082019050919050565b60006020820190508181036000830152610920816108e4565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000610983602683610792565b915061098e82610927565b604082019050919050565b600060208201905081810360008301526109b281610976565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006109ef602083610792565b91506109fa826109b9565b602082019050919050565b60006020820190508181036000830152610a1e816109e2565b905091905056fea264697066735822122050325d0ee500d4da2d97c2459a379df921076eb5b8b3594ec1d8edbe0c4c201764736f6c6343000809003300000000000000000000000027cd006548df7c8c8e9fdc4a67fa05c2e3ca5cf900000000000000000000000000000000000000000000000000000000000007e700000000000000000000000000000000000000000000000000000045d964b800000000000000000000000000000000000000000000000000007ee1f421682492

Deployed ByteCode

0x608060405234801561001057600080fd5b506004361061007d5760003560e01c80638f7807311161005b5780638f780731146100c8578063ae6180c2146100f8578063d66cc15314610116578063f2fde38b146101465761007d565b806312065fe014610082578063715018a6146100a05780638da5cb5b146100aa575b600080fd5b61008a610162565b60405161009791906105ec565b60405180910390f35b6100a8610214565b005b6100b2610228565b6040516100bf9190610648565b60405180910390f35b6100e260048036038101906100dd9190610694565b610251565b6040516100ef91906106dc565b60405180910390f35b6101006102c4565b60405161010d91906105ec565b60405180910390f35b610130600480360381019061012b9190610694565b610392565b60405161013d91906106dc565b60405180910390f35b610160600480360381019061015b9190610723565b610405565b005b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016101bf9190610648565b60206040518083038186803b1580156101d757600080fd5b505afa1580156101eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061020f9190610765565b905090565b61021c610489565b6102266000610507565b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600061025b610489565b6000821161029e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161029590610815565b60405180910390fd5b816003819055506003546002546102b59190610864565b60048190555060019050919050565b600080600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016103229190610648565b60206040518083038186803b15801561033a57600080fd5b505afa15801561034e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103729190610765565b90506002548110156103895760045491505061038f565b60009150505b90565b600061039c610489565b600082116103df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103d690610907565b60405180910390fd5b816002819055506003546002546103f69190610864565b60048190555060019050919050565b61040d610489565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561047d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161047490610999565b60405180910390fd5b61048681610507565b50565b6104916105cb565b73ffffffffffffffffffffffffffffffffffffffff166104af610228565b73ffffffffffffffffffffffffffffffffffffffff1614610505576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104fc90610a05565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b6000819050919050565b6105e6816105d3565b82525050565b600060208201905061060160008301846105dd565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061063282610607565b9050919050565b61064281610627565b82525050565b600060208201905061065d6000830184610639565b92915050565b600080fd5b610671816105d3565b811461067c57600080fd5b50565b60008135905061068e81610668565b92915050565b6000602082840312156106aa576106a9610663565b5b60006106b88482850161067f565b91505092915050565b60008115159050919050565b6106d6816106c1565b82525050565b60006020820190506106f160008301846106cd565b92915050565b61070081610627565b811461070b57600080fd5b50565b60008135905061071d816106f7565b92915050565b60006020828403121561073957610738610663565b5b60006107478482850161070e565b91505092915050565b60008151905061075f81610668565b92915050565b60006020828403121561077b5761077a610663565b5b600061078984828501610750565b91505092915050565b600082825260208201905092915050565b7f706c617374696350726f64756374696f6e206d7573742062652062696767657260008201527f207468616e203000000000000000000000000000000000000000000000000000602082015250565b60006107ff602783610792565b915061080a826107a3565b604082019050919050565b6000602082019050818103600083015261082e816107f2565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061086f826105d3565b915061087a836105d3565b92508261088a57610889610835565b5b828204905092915050565b7f6d61784275726e59656172206d75737420626520626967676572207468616e2060008201527f3000000000000000000000000000000000000000000000000000000000000000602082015250565b60006108f1602183610792565b91506108fc82610895565b604082019050919050565b60006020820190508181036000830152610920816108e4565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000610983602683610792565b915061098e82610927565b604082019050919050565b600060208201905081810360008301526109b281610976565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006109ef602083610792565b91506109fa826109b9565b602082019050919050565b60006020820190508181036000830152610a1e816109e2565b905091905056fea264697066735822122050325d0ee500d4da2d97c2459a379df921076eb5b8b3594ec1d8edbe0c4c201764736f6c63430008090033