Mare Bits Locker is a way to lock-up your ERC20, ERC721, or ERC1155 tokens and keep them safe from that waifu thief Brad. The contract issues a non-fungible token (NFT) that represents your deposit and allows whoever owns that token after a pre-determined length of time to withdraw the locked funds. Once locked, your tokens cannot be withdrawn until the lock period has expired no matter what. So, be careful!
This was created to facilitate the locking of liquidity tokens as part of the launch of Mare Bits ($MARE). For more information on that project, see https://mare.biz/. In order to make the code easily reviewable by others, I've released it here.
This should work for all tokens that implement either the ERC20, ERC721, or ERC1155 interfaces, including ERC777.
In order to use the Mare Bits Locker, your wallet must have a $MARE balance greater than zero.
Here are the deployed contract addresses. Please note, Etherscan/Polygonscan make interacting with verified contracts very easy and all of these are verified. Click the link below, then click on Read Contract to get data and Write Contract to execute functions that modify the block chain (you will need a wallet like Metamask if you are using the Write Contract functions).
-
Ethereum:
- Mare Bits Locker: (TBD)
- Mare Bits Locker Account: (TBD)
- Mare Bits Locker Token: (TBD)
- Mare Bits Vault: (TBD)
-
Polygon:
- Mare Bits Locker: 0xdFcB170bEa5b1B970574b8cCd0347A095256c4A8
- Mare Bits Locker Account: 0x7c20bfda6ba2cd5ca85b952696e279a2efcd5ff2
- Mare Bits Locker Token: 0xc12d120e3973e7bac07e1802ca0ea30676451642
- Mare Bits Vault: 0x3d41144b7236fb2119c52546d6f5df15c0c316a8
-
Ropsten (test network):
- Mare Bits Locker: 0xe8fFc80a8D5c07Eb9Cd52AbF1a081b588d663414
- Mare Bits Locker Account: 0xfc0c341d8522f896e569bce3641a873ae8dbe506
- Mare Bits Locker Token: 0x78910d0a3b750462e82699a40afec7c10332ec5c
- Mare Bits Vault: 0x1ef0433cc1646451b038617b9963f2afa6428cc1
(If you wish to use the Ropsten contract and need $MARE, please send your wallet address to iwtcits@mare.biz and I will send you some.)
Interaction will primarily be with the Mare Bits Locker, Mare Bits Locker Account, and Mare Bits Locker Token contracts. The Mare Bits Vault contract just holds deposits and doesn't offer much public functionality.
accounts() returns (IMarebitsLockerAccount)- Returns the address associated with the Mare Bits Locker Account contract.
bestPony() returns (string)- Returns the best pony.
extendLock(uint256 accountId, uint64 unlockTime) returns (uint256)- Sets the lock time for account
accountIdtounlockTime(in seconds since UNIX epoch). The new unlock time must be greater than the existing unlock time for the account (will throwTimeOutOfBoundsif not). Emits theTokensLockedevent and returns theaccountIdwhen successful. getAccount(uint256 accountId) returns (Account.Info)- Returns the account details for the account
accountId. These details include theaccountId, theamountof tokens locked, thetokenIdof the token locked, thetokenContractaddress, thetokenTypelocked, theunlockTime, whether or not the locker tokenisBurned, and whether or not the locker tokenisRedeemed. lockerToken() returns (IMarebitsLockerToken)- Returns the address associated with the Mare Bits Locker Token contract.
lockTokens(Token.Type tokenType, address tokenContract, uint256 tokenId, uint256 amount, uint64 unlockTime) returns (uint256)- Locks
amounttokens of thetokenTypetoken deployed at thetokenContractaddress with the token IDtokenIdfor a period represented byunlockTime(in seconds since UNIX epoch). ThetokenIdis ignored for ERC-20 tokens and theamountmust be1for ERC-721 tokens. Emits theTokensLockedevent and returns the newly createdaccountIdwhen successful. mareBitsToken() returns (IERC20)- Returns the address associated with the Mare Bits token contract. (This function is private in the Polygon contract.)
redeemToken(uint256 accountId)- Redeems the token for the account
accountId, returning the locked tokens to the owner ofaccountId. This will throw aTimeOutOfBoundserror if attempted beforeunlockTimehas expired. Emits theTokenRedeemedevent when successful. supportsInterface(bytes4 interfaceId) returns (bool)- See ERC-165.
vault() returns (IMarebitsVault)- Returns the address associated with the Mare Bits Vault contract.
TokensLocked(uint256 indexed accountId, address indexed owner, uint256 amount, address tokenContract, uint256 tokenId, Token.Type tokenType, uint64 unlockTime)- Emitted whenever a new locker is created or whenever the
unlockTimefor an existing locker has been extended. TokenRedeemed(uint256 indexed accountId, address indexed owner, uint256 amount, address tokenContract, uint256 tokenId, Token.Type tokenType)- Emitted whenever a locker token is redeemed and the deposited tokens are returned to the
owner.
InsufficientBalance(uint256 required, uint256 available)- Thrown when the required balance is less than the available balance.
InvalidAmount(string reason)- Thrown when an invalid amount is entered. The
reasonshould contain the reason why the amount was invalid. InvalidCaller()- Thrown when called by an invalid caller (such as a contract instead of a real wallet).
InvalidTokenType(Token.Type tokenType)- Thrown when the
tokenTypeis not valid. Must be 1 for ERC-1155, 2 for ERC-20, or 3 for ERC-721. LockedAccount(uint64 expiresAt, uint64 currentTime)- Thrown when attempting to call
redeemTokenfor an account that is still locked.expiresAtis the time when the lock expires (in seconds since UNIX epoch) andcurrentTimeis the current block time stamp (in seconds since UNIX epoch). NeedsMoreMARE(address wallet)- Thrown when someone attempts to interact with this contract who does not hodl $MARE. You must have a balance greater than 0.
NonexistentAccount(uint256 accountId)- Thrown when the account
accountIddoesn't exist. NotTokenOwner(uint256 tokenId, address claimedOwner, address actualOwner)- Thrown when attempting to lock the token
tokenIdbyclaimedOwnerwhen the actual owner isactualOwner. TimeOutOfBounds(uint64 given, uint64 minimum, uint64 maximum)- Thrown when the
giventime does not fall within the range specified byminimumandmaximum. UnapprovedTokenTransfer(address tokenAddress, string approvalFunction)- Thrown when attempting to transfer tokens for token contract
tokenAddress. TheapprovalFunctiontells you what function needs to be run on thetokenAddresscontract to approve the transfer. ZeroAmountGiven()- Thrown when a zero amount is passed.
Token.Type- Is an enumerated value represented internally as a
uint8where:0meansUNDEFINED1meansERC-11552meansERC-203meansERC-721
Account.Info- Is a data structure (or object) with the following members:
uint256 accountId- The account ID
uint256 amount- The amount of tokens locked in the account
uint256 tokenId- The token ID for the tokens locked in the account (only meaningful for ERC-1155 and ERC-721 tokens, will be 0 for ERC-20 tokens)
address tokenContract- The address of the token contract for the locked tokens
uint64 unlockTime- The time after which the account token can be redeemed to withdraw the locked token balance (in seconds since UNIX epoch)
bool isBurned- True when the account token has been burned; otherwise, false
bool isRedeemed- True when the tokens locked by the account have been redeemed; otherwise, false
bestPony() returns (string)- Returns the best pony.
getAccount(uint256 accountId) returns (Account.Info)- Returns the account details for the account
accountId. These details include theaccountId, theamountof tokens locked, thetokenIdof the token locked, thetokenContractaddress, thetokenTypelocked, theunlockTime, whether or not the locker tokenisBurned, and whether or not the locker tokenisRedeemed. supportsInterface(bytes4 interfaceId) returns (bool)- See ERC-165.
NonexistentAccount(uint256 accountId)- Thrown when the account
accountIddoesn't exist.
This contract represents the ERC-721 token issued when tokens are locked. As such, it extends all the functions and events from the ERC-721 specification.
approve(address to, uint256 tokenId)- Gives permission to
toto transfer tokentokenIdto another account. The approval is cleared when the token is transferred. Only a single account can be approved at a time, so approving the zero address clears previous approvals. Emits anApprovalevent when successful. balanceOf(address owner) returns (uint256)- Returns the number of Mare Bits Locker tokens held by address
owner. bestPony() returns (string)- Returns the best pony.
burn(uint256 tokenId)- Can only be called by the owner of the token
tokenIdor someone the owner has approved. This will burn the locker token, in effect sending it to the zero address. If this is called, the token will disappear and any tokens locked in the locker will be unredeemable! Emits aTransferevent when successful. getApproved(uint256 tokenId) returns (address)- Returns the account approved to transfer token
tokenId. isApprovedForAll(address owner, address operator) returns (bool)- Returns true if the
operatoris allowed to manage all of the assets ofowner. name() returns (string)- Returns the general name of this token (Mare Bits Locker Token).
ownerOf(uint256 tokenId) returns (address)- Returns the address that owns the token
tokenId. safeTransferFrom(address from, address to, uint256 tokenId)- Safely transfers token
tokenIdfromfromtoto, checking first that contract recipients are aware of the ERC-721 protocol to prevent tokens from being forever locked. Emits aTransferevent when successful. setApprovalForAll(address operator, bool _approved)- Approve or remove
operatoras an operator for the caller. Operators can calltransferFromorsafeTransferFromfor any token owned by the caller. Emits anApprovalForAllevent when successful. supportsInterface(bytes4 interfaceId) returns (bool)- See ERC-165.
symbol() returns (string)- Returns the general symbol of this token (๐โโ๏ธ๐๐ช).
tokenByIndex(uint256 index) returns (uint256)- REturns a token ID at a given
indexof all Mare Bit Locker Tokens. Use along withtotalSupplyto enumerate all tokens. tokenOfOwnerByIndex(address owner, uint256 index) returns (uint256)- Returns a token ID owned by
ownerat a givenindexof its token list. Use along withbalanceOfto enumerate all ofowner's tokens. tokenURI(uint256 tokenId)- Returns the URI containing metadata for the token
tokenId. This is used by sites to display metadata for this NFT. totalSupply() returns (uint256)- Returns the total amount of Mare Bit Locker Tokens.
transferFrom(address from, address to, uint256 tokenId)- Transfers token
tokenIdfromfromtoto. Emits aTransferevent when successful.
Approval(address owner, address approved, uint256 tokenId)- Emitted when
ownerenabledapprovedto manager the tokentokenId. ApprovalForAll(address owner, address operator, bool approved)- Emitted when
ownerenables or disables (approved)operatorto manager all of its assets. Transfer(address from, address to, uint256 tokenId)- Emitted when token
tokenIdis transferred fromfromtoto. URI(string value, uint256 indexed id)- Emitted when the URI of the token
idhas changed tovalue.
NotApprovedOrOwner(uint256 tokenId)- Thrown when attempted to transfer a token the caller does not own or is not approved to transfer.
NotLockerOwner(address claimedOwner, address actualOwner)- Thrown when attempted to make a call that only the owner of this contract's owner can make.
bestPony() returns (string)- Returns the best pony.
onERC1155BatchReceived(address operator, address from, uint256[] ids, uint256[] values, bytes data) returns (bytes4)- Handles the receipt of multiple ERC-1155 token types. This function is called at the end of a
safeBatchTransferFromafter the balances have been updated. It returns its Solidity selector to confirm the token transfers. onERC1155Received(address operator, address from, uint256 id, uint256 value, bytes data) returns (bytes4)- Handles the receipt of a single ERC-1155 token type. This function is called at the end of a
safeTransferFromafter the balance has been updated. It returns its Solidity selector to confirm the token transfer. onERC721Received(address operator, address from, uint256 tokenId, bytes data) returns (bytes4)- Whenever an ERC-721
tokenIdis transferred to this contract viasafeTransferFrombyoperatorfromfrom, this function is called. It returns its Solidity selector to confirm the token transfer. supportsInterface(bytes4 interfaceId) returns (bool)- See ERC-165.