Feature Tip: Add private address tag to any address under My Name Tag !
Latest 6 from a total of 6 transactions
| Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Withdraw Tokens | 23120499 | 86 days ago | IN | 0 ETH | 0.00008833 | ||||
| Withdraw Tokens | 21844906 | 265 days ago | IN | 0 ETH | 0.000186 | ||||
| Withdraw Tokens | 21396540 | 327 days ago | IN | 0 ETH | 0.00150584 | ||||
| Withdraw Tokens | 21388375 | 329 days ago | IN | 0 ETH | 0.00281486 | ||||
| Early Withdraw T... | 20965294 | 388 days ago | IN | 0 ETH | 0.00343488 | ||||
| Early Withdraw T... | 16434552 | 1023 days ago | IN | 0 ETH | 0.00304235 |
Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
To
|
|||
|---|---|---|---|---|---|---|---|
| 0x3d602d80 | 16176418 | 1059 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Minimal Proxy Contract for 0xc5a00a96e6a7039dad5af5c41584469048b26038
Contract Name:
OptiVault
Compiler Version
v0.8.4+commit.c7e474f2
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
pragma solidity ^0.8.4;
import '@uniswap/v2-periphery/contracts/interfaces/IERC20.sol';
interface IOptiVaultBalanceLookup {
function sharesOf(address user) external view returns (uint256 _shares); //shares
}
contract OptiVault {
// **********************************************************************************
// * OptiVaults provide an easy way to lock tokens as a group. *
// * Reflective staking means that early withdrawals are allowed, *
// * for a 20% penalty that is distributed to everyone else. *
// **********************************************************************************
bool private initialized;
IERC20 public token;
uint256 public lockupDate; // deposits cannot be made after this
uint256 public minimumTokenCommitment; // deposited tokens must exceed this amount to lock
bool public failed; // campaign failed to reach minimum and is not subject to lock
bool public succeeded; // campaign reached minimum and is locked
uint256 public withdrawalsLockedUntilTimestamp; // time at which haircut-free withdrawal is available.
mapping (address => uint256) private shareBalance; // internal balance tracking for self-contained campaigns
uint256 private totalShares; // the denominator which decreases faster than the token balance
IOptiVaultBalanceLookup public shareBalanceLookup; // external balance tracking for use by other contracts
mapping (address => bool) public withdrawn; // instead of zeroing share balances, this flag is set.
function initialize(address _token, uint256 _lockupDate, uint256 _minimumTokenCommitment, uint256 _withdrawalsLockedUntilTimestamp, address _balanceLookup) external {
require(!initialized);
token = IERC20(_token);
lockupDate = _lockupDate;
minimumTokenCommitment = _minimumTokenCommitment;
withdrawalsLockedUntilTimestamp = _withdrawalsLockedUntilTimestamp;
if (lockupDate == 0) {
totalShares = token.balanceOf(address(this));
}
shareBalanceLookup = IOptiVaultBalanceLookup(_balanceLookup);
initialized = true;
}
function unlockTimestamp() external view returns (uint256 _unlockTimestamp) {
_unlockTimestamp = withdrawalsLockedUntilTimestamp;
}
function sharesOf(address user) external view returns (uint256 _shares) {
//Shares in the staking venture.
_shares = shareBalance[user];
}
function tokenBalanceOf(address user) external view returns (uint256 _amount) {
//The number of tokens redeemable by the user's share.
if (withdrawn[msg.sender]) {
return 0;
}
uint256 shares = shareBalanceLookup.sharesOf(user);
_amount = (shares * token.balanceOf(address(this))) / totalShares;
}
function tokenLocked() external view returns (address _token) {
_token = address(token);
}
function withdrawable() public view returns (bool) {
return (failed || block.timestamp >= withdrawalsLockedUntilTimestamp);
}
function contribute(uint tokenAmount) public {
require(block.timestamp < lockupDate, "OptiVault: Pooling phase has ended.");
token.transferFrom(msg.sender, address(this), tokenAmount);
shareBalance[msg.sender] += tokenAmount;
totalShares += tokenAmount;
if (token.balanceOf(address(this)) >= minimumTokenCommitment) {
succeeded = true;
}
}
function fail() public {
require(block.timestamp > lockupDate, "OptiVault: Still in Pooling phase.");
require(token.balanceOf(address(this)) < minimumTokenCommitment, "OptiVault: Staking succesful.");
require(!succeeded, "OptiVault: Campaign already succeeded.");
require(!failed, "OptiVault: Campaign already marked failed.");
failed = true;
}
function earlyWithdrawTokens() public {
require(withdrawn[msg.sender] == false, "OptiVault: Already withdrawn.");
require(block.timestamp > lockupDate, "OptiVault: Still in Pooling phase.");
require(!withdrawable(), "OptiVault: Staking period has ended.");
uint userTokenBalance = this.tokenBalanceOf(msg.sender);
uint userShareBalance = shareBalanceLookup.sharesOf(msg.sender);
uint toTransfer;
if (userShareBalance == totalShares) {
toTransfer = userTokenBalance;
} else {
toTransfer = userTokenBalance * 80 / 100;
}
totalShares -= userShareBalance;
token.transfer(msg.sender, toTransfer);
withdrawn[msg.sender] = true;
}
function withdrawTokens() public {
require(withdrawable(), "OptiVault: Tokens still locked.");
require(withdrawn[msg.sender] == false, "OptiVault: Already withdrawn.");
uint toTransfer = this.tokenBalanceOf(msg.sender);
token.transfer(msg.sender, toTransfer);
totalShares -= shareBalanceLookup.sharesOf(msg.sender);
withdrawn[msg.sender] = true;
}
}pragma solidity >=0.5.0;
interface IERC20 {
event Approval(address indexed owner, address indexed spender, uint value);
event Transfer(address indexed from, address indexed to, uint value);
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
function totalSupply() external view returns (uint);
function balanceOf(address owner) external view returns (uint);
function allowance(address owner, address spender) external view returns (uint);
function approve(address spender, uint value) external returns (bool);
function transfer(address to, uint value) external returns (bool);
function transferFrom(address from, address to, uint value) external returns (bool);
}{
"optimizer": {
"enabled": false,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract ABI
API[{"inputs":[{"internalType":"uint256","name":"tokenAmount","type":"uint256"}],"name":"contribute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"earlyWithdrawTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"fail","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"failed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_lockupDate","type":"uint256"},{"internalType":"uint256","name":"_minimumTokenCommitment","type":"uint256"},{"internalType":"uint256","name":"_withdrawalsLockedUntilTimestamp","type":"uint256"},{"internalType":"address","name":"_balanceLookup","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lockupDate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minimumTokenCommitment","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"shareBalanceLookup","outputs":[{"internalType":"contract IOptiVaultBalanceLookup","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"sharesOf","outputs":[{"internalType":"uint256","name":"_shares","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"succeeded","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"tokenBalanceOf","outputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenLocked","outputs":[{"internalType":"address","name":"_token","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unlockTimestamp","outputs":[{"internalType":"uint256","name":"_unlockTimestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawalsLockedUntilTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"withdrawn","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|---|---|---|---|---|
| ETH | 100.00% | $0.00 | 0.2066 | $0.00 |
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.