Skip to main content

popCORN ($POPCORN) Implementation

GitHub Repo

The popCORN implementation is available on the following repo.

Contract Address

0x9Cf9F00F3498c2ac856097087e041523dfdD71fF

Overview

  • ERC20 wrapper contract with a built-in linear vesting mechanism
  • Inherits from OpenZeppelin contracts, and adds custom whitelisting and locking logic
  • Implements a flexible whitelist system to distinguish between standard users, admins, and distributors
  • popCORN is non-transferable by default, but allows certain permissions for whitelisted accounts
  • Vesting bags are tracked by lock timestamps and managed with EnumerableMap
  • Vesting forfeits (when withdrawing early) are redirected to a designated remainder receiver
  • Upgradeable using UUPS proxy

Inherits: ERC20WrapperUpgradeable, PausableUpgradeable, AuthUpgradeable, UUPSUpgradeable

Key Concepts

Whitelist Roles

StatusValueDescription
None0Standard users subject to vesting
Admin1Privileged users that bypass vesting rules
Distributor2Entities that distribute popCORN but cannot unwrap

popCORN Vesting

Each user has individual "vesting bags" represented by normalized timestamps. All rewards for a given day across the ecosystem are grouped into a single bag. Bags vest linearly over 21 weeks:

  • 21% of the $CORN is immediately claimable
  • 79% vests linearly over 21 weeks
  • Early withdrawal forfeits the remaining unvested $CORN

Withdrawals are executed using withdrawToByLockTimestamps().

Functions

__ERC20WrapperLocked_init

Initializes the contract with the provided parameters.

function __ERC20WrapperLocked_init(
address _owner,
address _authority,
address _remainderReceiver,
address _underlying,
string memory _name,
string memory _symbol
) internal onlyInitializing;

depositFor

Used by authorized addresses to deposit and wrap tokens for a user.

function depositFor(address account, uint256 amount) public returns (bool);

withdrawTo

Used by authorized addresses to unwrap tokens to a user.

function withdrawTo(address account, uint256 amount) public returns (bool);

withdrawToByLockTimestamps

Withdraws unlocked portions of specified vesting bags.

function withdrawToByLockTimestamps(address account, uint256[] memory lockTimestamps, bool allowRemainderLoss) public returns (bool);

getLockedAmountsWithClaimable

Returns an array of bags along with their total and claimable amounts.

function getLockedAmountsWithClaimable(address account) public view returns (uint256[] memory, uint256[] memory, uint256[] memory);

setWhitelistStatus

Sets or downgrades an account's whitelist status.

function setWhitelistStatus(address account, uint256 status) public;
function setWhitelistStatus(uint256 status) public;

pause / unpause

Pauses or resumes all sensitive contract actions.

function pause() external;
function unpause() external;

_authorizeUpgrade

Authorization hook for UUPS upgrades.

function _authorizeUpgrade(address newImplementation) internal override;

Notes

  • Standard users can only interact with popCORN according to their vesting schedule.
  • popCORN is not transferrable under normal conditions.
  • Whitelisted admin accounts can bypass these restrictions for operational flexibility.

For more information, visit the Corn App to view and manage vesting schedules.