Address Contract Verified
Address
0x6397B894b1C68951Bb7164979bf8a95CCebA540b
Balance
0 ETH
Nonce
1
Code Size
8910 bytes
Creator
0x8550d5Cc...3D8E at tx 0xfb6225c0...ec7895
Indexed Transactions
0 (1 on-chain, 1.1% indexed)
Contract Bytecode
8910 bytes
0x608060405234801561001057600080fd5b50600436106101735760003560e01c806398b3f7e2116100de578063d3b8800311610097578063f2aa821811610071578063f2aa8218146103ef578063f2fde38b14610402578063f33548b514610415578063fc0c546a1461041d57600080fd5b8063d3b88003146103b6578063e3083884146103c9578063f18fa08a146103dc57600080fd5b806398b3f7e21461033e578063a932c47a14610351578063b187bd2614610364578063b217f9d414610388578063c0ac58751461039b578063c4ae3168146103ae57600080fd5b8063545f1a2e11610130578063545f1a2e1461024657806379d973d914610259578063881644681461026c5780638da5cb5b146102a05780638f0164f6146102b357806396fe05821461032d57600080fd5b806302c7e7af1461017857806302d05d3f146101af578063084f1df5146101ee5780630be8639714610216578063144fa6d71461022b5780634451d89f1461023e575b600080fd5b60015461019290600160801b90046001600160801b031681565b6040516001600160801b0390911681526020015b60405180910390f35b6101d67f0000000000000000000000008550d5cc00d89fabb6f52cbdaeda948af9833d8e81565b6040516001600160a01b0390911681526020016101a6565b6101f6610430565b604080516001600160801b039384168152929091166020830152016101a6565b610229610224366004611eac565b61054b565b005b610229610239366004611f34565b6108b7565b6102296108ed565b610229610254366004611eac565b610c0d565b610229610267366004611eac565b610eb6565b6101f661027a366004611f6d565b6005602052600090815260409020546001600160801b0380821691600160801b90041682565b6000546101d6906001600160a01b031681565b6102fa6102c1366004611f34565b600460205260009081526040902080546001909101546001600160801b0380831692600160801b90819004821692808316929190041684565b604080516001600160801b03958616815293851660208501529184169183019190915290911660608201526080016101a6565b6003546040519081526020016101a6565b61022961034c366004611f88565b611072565b61022961035f366004611eac565b611344565b60005461037890600160a81b900460ff1681565b60405190151581526020016101a6565b600154610192906001600160801b031681565b6102296103a9366004611eac565b611628565b61022961165e565b6102296103c4366004611fca565b6116a9565b6102296103d7366004611ffd565b6117a6565b6102296103ea366004611eac565b611880565b6101d66103fd36600461207e565b611a31565b610229610410366004611f34565b611a5b565b610229611acd565b6002546101d6906001600160a01b031681565b6001805460009182916001600160801b03169082905b826001600160801b0316816001600160801b031611610544576001600160801b038082166000908152600560209081526040918290208251808401909352548084168352600160801b9004909216918101829052906104a590846120ad565b92504281600001516001600160801b0316111580156104ef5750600560006104ce8460016120ad565b6001600160801b039081168252602082019290925260400160002054164211155b806105205750836001600160801b0316826001600160801b0316148015610520575080516001600160801b03164210155b156105315781955082945050610544565b508061053c816120d8565b915050610446565b5050509091565b6000546001600160a01b0316331461057e5760405162461bcd60e51b8152600401610575906120fe565b60405180910390fd5b82811461059d5760405162461bcd60e51b81526004016105759061211e565b60005b61ffff81168411156108b0576000858561ffff84168181106105c4576105c461213d565b90506020020160208101906105d99190611f34565b6001600160a01b0316148061061f575082828261ffff168181106105ff576105ff61213d565b90506020020160208101906106149190611f6d565b6001600160801b0316155b61089e5760006004600087878561ffff1681811061063f5761063f61213d565b90506020020160208101906106549190611f34565b6001600160a01b0316815260208082019290925260409081016000908120825160808101845281546001600160801b038082168352600160801b918290048116968301879052600190930154808416958301959095529093041660608301529092500361078e57600386868461ffff168181106106d3576106d361213d565b90506020020160208101906106e89190611f34565b815460018082018455600093845260209093200180546001600160a01b0319166001600160a01b03929092169190911790556003546107279190612153565b6004600088888661ffff168181106107415761074161213d565b90506020020160208101906107569190611f34565b6001600160a01b03168152602081019190915260400160002080546001600160801b0319166001600160801b03929092169190911790555b83838361ffff168181106107a4576107a461213d565b90506020020160208101906107b99190611f6d565b81602001516107c891906120ad565b6004600088888661ffff168181106107e2576107e261213d565b90506020020160208101906107f79190611f34565b6001600160a01b03168152602081019190915260400160002080546001600160801b03928316600160801b029216919091179055838361ffff84168181106108415761084161213d565b90506020020160208101906108569190611f6d565b60018054601090610878908490600160801b90046001600160801b03166120ad565b92506101000a8154816001600160801b0302191690836001600160801b03160217905550505b806108a88161216a565b9150506105a0565b5050505050565b6000546001600160a01b031633146108e15760405162461bcd60e51b8152600401610575906120fe565b6108ea81611b3e565b50565b6000806108f8610430565b336000908152600460209081526040808320815160808101835281546001600160801b038082168352600160801b918290048116958301959095526001909201548085169382019390935291049091166060820152905492945090925090600160a81b900460ff1615801561097657506000836001600160801b0316115b801561098c57506002546001600160a01b031615155b6109c35760405162461bcd60e51b8152602060048201526008602482015267085cdd185c9d195960c21b6044820152606401610575565b600081602001516001600160801b031611610a095760405162461bcd60e51b815260206004820152600660248201526510b13abcb2b960d11b6044820152606401610575565b816001600160801b031681604001516001600160801b031610610a585760405162461bcd60e51b815260206004820152600760248201526618db185a5b595960ca1b6044820152606401610575565b600081604001516001600160801b0316600003610a9357612710838360200151610a829190612181565b610a8c91906121b0565b9050610abe565b60608201516040830151610aa78583612181565b610ab191906121b0565b610abb91906121e4565b90505b6002546040516370a0823160e01b81523060048201526001600160801b038316916001600160a01b0316906370a0823190602401602060405180830381865afa158015610b0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b33919061220c565b10158015610b4a57506000816001600160801b0316115b610b855760405162461bcd60e51b815260206004820152600c60248201526b1a5b9cdd59999a58da595b9d60a21b6044820152606401610575565b33600090815260046020526040902060010180546001600160801b0319166001600160801b0385161790556060820151610bc09082906120ad565b33600081815260046020526040902060010180546001600160801b03938416600160801b02908416179055600254610c07926001600160a01b039190911691908416611b60565b50505050565b6000546001600160a01b03163314610c375760405162461bcd60e51b8152600401610575906120fe565b8281148015610c47575060035415155b610c635760405162461bcd60e51b81526004016105759061211e565b60005b61ffff81168411156108b05760006004600087878561ffff16818110610c8e57610c8e61213d565b9050602002016020810190610ca39190611f34565b6001600160a01b031681526020808201929092526040908101600020815160808101835281546001600160801b038082168352600160801b9182900481169583018690526001909301548084169483019490945290920416606082015291501580610d1b5750600081604001516001600160801b0316115b80610d5957506000868661ffff8516818110610d3957610d3961213d565b9050602002016020810190610d4e9190611f34565b6001600160a01b0316145b80610d95575083838361ffff16818110610d7557610d7561213d565b9050602002016020810190610d8a9190611f6d565b6001600160801b0316155b15610da05750610ea4565b83838361ffff16818110610db657610db661213d565b9050602002016020810190610dcb9190611f6d565b6020820151600154610ded9190600160801b90046001600160801b03166121e4565b610df791906120ad565b600180546001600160801b03928316600160801b029216919091179055838361ffff8416818110610e2a57610e2a61213d565b9050602002016020810190610e3f9190611f6d565b6004600088888661ffff16818110610e5957610e5961213d565b9050602002016020810190610e6e9190611f34565b6001600160a01b03168152602081019190915260400160002080546001600160801b03928316600160801b029216919091179055505b80610eae8161216a565b915050610c66565b6000546001600160a01b03163314610ee05760405162461bcd60e51b8152600401610575906120fe565b828114610eff5760405162461bcd60e51b81526004016105759061211e565b6000610f09610430565b506001549091506001600160801b031660005b6001600160801b03811686111561106957816001600160801b03168787836001600160801b0316818110610f5257610f5261213d565b9050602002016020810190610f679190611f6d565b6001600160801b03161180610fbd57508686826001600160801b0316818110610f9257610f9261213d565b9050602002016020810190610fa79190611f6d565b6001600160801b0316836001600160801b031610155b611057578484826001600160801b0316818110610fdc57610fdc61213d565b9050602002016020810190610ff19190611f6d565b600560008989856001600160801b03168181106110105761101061213d565b90506020020160208101906110259190611f6d565b6001600160801b039081168252602082019290925260400160002080546001600160801b031916929091169190911790555b80611061816120d8565b915050610f1c565b50505050505050565b6000546001600160a01b0316331461109c5760405162461bcd60e51b8152600401610575906120fe565b6003546110bb5760405162461bcd60e51b81526004016105759061211e565b60005b61ffff811682111561133f5760006004600085858561ffff168181106110e6576110e661213d565b90506020020160208101906110fb9190611f34565b6001600160a01b031681526020808201929092526040908101600020815160808101835281546001600160801b038082168352600160801b918290048116958301869052600190930154808416948301949094529092041660608201529150158061119957506000848461ffff85168181106111795761117961213d565b905060200201602081019061118e9190611f34565b6001600160a01b0316145b156111a4575061132d565b6020810151600180546010906111cb908490600160801b90046001600160801b03166121e4565b92506101000a8154816001600160801b0302191690836001600160801b031602179055506000600360016003805490506112059190612153565b815481106112155761121561213d565b6000918252602090912001548251600380546001600160a01b039093169350839290916001600160801b03169081106112505761125061213d565b600091825260208083209190910180546001600160a01b0319166001600160a01b0394851617905584519284168252600490526040902080546001600160801b0319166001600160801b0390921691909117905560038054806112b5576112b5612225565b600082815260208120820160001990810180546001600160a01b0319169055909101909155600490868661ffff87168181106112f3576112f361213d565b90506020020160208101906113089190611f34565b6001600160a01b03168152602081019190915260400160009081208181556001015550505b806113378161216a565b9150506110be565b505050565b6000546001600160a01b0316331461136e5760405162461bcd60e51b8152600401610575906120fe565b828114801561137e575060035415155b61139a5760405162461bcd60e51b81526004016105759061211e565b60005b61ffff81168411156108b05760006004600087878561ffff168181106113c5576113c561213d565b90506020020160208101906113da9190611f34565b6001600160a01b031681526020808201929092526040908101600020815160808101835281546001600160801b038082168352600160801b918290048116958301869052600190930154808416948301949094529092041660608201529150158061147857506000868661ffff85168181106114585761145861213d565b905060200201602081019061146d9190611f34565b6001600160a01b0316145b806114b657506000848461ffff85168181106114965761149661213d565b90506020020160208101906114ab9190611f34565b6001600160a01b0316145b156114c15750611616565b83838361ffff168181106114d7576114d761213d565b90506020020160208101906114ec9190611f34565b600382600001516001600160801b03168154811061150c5761150c61213d565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550806004600086868661ffff168181106115555761155561213d565b905060200201602081019061156a9190611f34565b6001600160a01b03168152602080820192909252604090810160009081208451938501516001600160801b03948516600160801b9186168202178255928501516060909501519484169490931690910292909217600190910155600490878761ffff86168181106115dd576115dd61213d565b90506020020160208101906115f29190611f34565b6001600160a01b031681526020810191909152604001600090812081815560010155505b806116208161216a565b91505061139d565b6000546001600160a01b031633146116525760405162461bcd60e51b8152600401610575906120fe565b610c0784848484611c74565b6000546001600160a01b031633146116885760405162461bcd60e51b8152600401610575906120fe565b6000805460ff60a81b198116600160a81b9182900460ff1615909102179055565b6000546001600160a01b031633146116d35760405162461bcd60e51b8152600401610575906120fe565b6001600160a01b0382166116f95760405162461bcd60e51b81526004016105759061211e565b6002546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015611742573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611766919061220c565b9050806001600160801b0316826001600160801b03161115611786578091505b60025461133f906001600160a01b0316846001600160801b038516611b60565b600054600160a01b900460ff16156117ee5760405162461bcd60e51b815260206004820152600b60248201526a125b9a5d1a585b1a5e995960aa1b6044820152606401610575565b336001600160a01b037f0000000000000000000000008550d5cc00d89fabb6f52cbdaeda948af9833d8e16146118515760405162461bcd60e51b815260206004820152600860248201526710b1b932b0ba37b960c11b6044820152606401610575565b61185a85611b3e565b61186684848484611c74565b50506000805460ff60a01b1916600160a01b179055505050565b6000546001600160a01b031633146118aa5760405162461bcd60e51b8152600401610575906120fe565b8281146118c95760405162461bcd60e51b81526004016105759061211e565b60006118d3610430565b506001549091506001600160801b031660005b6001600160801b03811686111561106957816001600160801b03168787836001600160801b031681811061191c5761191c61213d565b90506020020160208101906119319190611f6d565b6001600160801b0316118061198757508686826001600160801b031681811061195c5761195c61213d565b90506020020160208101906119719190611f6d565b6001600160801b0316836001600160801b031610155b611a1f578484826001600160801b03168181106119a6576119a661213d565b90506020020160208101906119bb9190611f6d565b600560008989856001600160801b03168181106119da576119da61213d565b90506020020160208101906119ef9190611f6d565b6001600160801b039081168252602082019290925260400160002080548216600160801b93909216929092021790555b80611a29816120d8565b9150506118e6565b60038181548110611a4157600080fd5b6000918252602090912001546001600160a01b0316905081565b6000546001600160a01b03163314611a855760405162461bcd60e51b8152600401610575906120fe565b6001600160a01b038116611aab5760405162461bcd60e51b81526004016105759061211e565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b03163314611af75760405162461bcd60e51b8152600401610575906120fe565b60018054600091611b10916001600160801b03166121e4565b6001600160801b0316600081815260056020526040812055600180546001600160801b031916909117905550565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b1790529151600092839290871691611bbc919061223b565b6000604051808303816000865af19150503d8060008114611bf9576040519150601f19603f3d011682016040523d82523d6000602084013e611bfe565b606091505b5091509150818015611c28575080511580611c28575080806020019051810190611c289190612276565b6108b05760405162461bcd60e51b815260206004820152601f60248201527f5472616e7366657248656c7065723a205452414e534645525f4641494c4544006044820152606401610575565b828114611c935760405162461bcd60e51b81526004016105759061211e565b6001546001600160801b031660005b6001600160801b038116851115611e3957611cbe600186612153565b816001600160801b031614611d66578585611cda8360016120ad565b6001600160801b0316818110611cf257611cf261213d565b9050602002016020810190611d079190611f6d565b6001600160801b03168686836001600160801b0316818110611d2b57611d2b61213d565b9050602002016020810190611d409190611f6d565b6001600160801b031610611d665760405162461bcd60e51b81526004016105759061211e565b611d716001836120ad565b915060405180604001604052808787846001600160801b0316818110611d9957611d9961213d565b9050602002016020810190611dae9190611f6d565b6001600160801b031681526020018585846001600160801b0316818110611dd757611dd761213d565b9050602002016020810190611dec9190611f6d565b6001600160801b039081169091528381166000908152600560209081526040909120835193909101518216600160801b029290911691909117905580611e31816120d8565b915050611ca2565b50600180546001600160801b0319166001600160801b039290921691909117905550505050565b60008083601f840112611e7257600080fd5b50813567ffffffffffffffff811115611e8a57600080fd5b6020830191508360208260051b8501011115611ea557600080fd5b9250929050565b60008060008060408587031215611ec257600080fd5b843567ffffffffffffffff80821115611eda57600080fd5b611ee688838901611e60565b90965094506020870135915080821115611eff57600080fd5b50611f0c87828801611e60565b95989497509550505050565b80356001600160a01b0381168114611f2f57600080fd5b919050565b600060208284031215611f4657600080fd5b611f4f82611f18565b9392505050565b80356001600160801b0381168114611f2f57600080fd5b600060208284031215611f7f57600080fd5b611f4f82611f56565b60008060208385031215611f9b57600080fd5b823567ffffffffffffffff811115611fb257600080fd5b611fbe85828601611e60565b90969095509350505050565b60008060408385031215611fdd57600080fd5b611fe683611f18565b9150611ff460208401611f56565b90509250929050565b60008060008060006060868803121561201557600080fd5b61201e86611f18565b9450602086013567ffffffffffffffff8082111561203b57600080fd5b61204789838a01611e60565b9096509450604088013591508082111561206057600080fd5b5061206d88828901611e60565b969995985093965092949392505050565b60006020828403121561209057600080fd5b5035919050565b634e487b7160e01b600052601160045260246000fd5b60006001600160801b038083168185168083038211156120cf576120cf612097565b01949350505050565b60006001600160801b038083168181036120f4576120f4612097565b6001019392505050565b60208082526006908201526510b7bbb732b960d11b604082015260600190565b6020808252600590820152640859dbdbd960da1b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b60008282101561216557612165612097565b500390565b600061ffff8083168181036120f4576120f4612097565b60006001600160801b03808316818516818304811182151516156121a7576121a7612097565b02949350505050565b60006001600160801b03808416806121d857634e487b7160e01b600052601260045260246000fd5b92169190910492915050565b60006001600160801b038381169083168181101561220457612204612097565b039392505050565b60006020828403121561221e57600080fd5b5051919050565b634e487b7160e01b600052603160045260246000fd5b6000825160005b8181101561225c5760208186018101518583015201612242565b8181111561226b576000828501525b509190910192915050565b60006020828403121561228857600080fd5b81518015158114611f4f57600080fdfea264697066735822122061bbe1733724d98498cd2149be97dbabacd758907a2f43d369c281c17f265d5564736f6c634300080d0033
Verified Source Code Full Match
Compiler: v0.8.13+commit.abaa5c0e
EVM: london
Optimization: Yes (200 runs)
FixedVesting.sol 335 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "./TransferHelper.sol";
import "./IFixedCreator.sol";
contract FixedVesting{
address public immutable creator = msg.sender;
address public owner = tx.origin;
bool private initialized;
bool public isPaused;
uint128 public vestingLength;
uint128 public sold;
address public token;
address[] public buyers;
struct Detail{
uint128 datetime;
uint128 ratio_d2;
}
struct Bought{
uint128 buyerIndex;
uint128 purchased;
uint128 completed_d2; // in percent (2 decimal)
uint128 claimed;
}
mapping(address => Bought) public invoice;
mapping(uint128 => Detail) public vesting;
modifier onlyOwner{
require(msg.sender == owner, "!owner");
_;
}
/**
* @dev Initialize vesting token distribution
* @param _token Token project address
* @param _datetime Vesting datetime in epoch
* @param _ratio_d2 Vesting ratio in percent (decimal 2)
*/
function initialize(
address _token,
uint128[] calldata _datetime,
uint128[] calldata _ratio_d2
) external {
require(!initialized, "Initialized");
require(msg.sender == creator, "!creator");
_setToken(_token);
_newVesting(_datetime, _ratio_d2);
initialized = true;
}
/**
* @dev Get length of buyer
*/
function getBuyerLength() external view returns (uint){
return buyers.length;
}
/**
* @dev Get vesting runnning
*/
function vestingRunning() public view returns(uint128 round, uint128 totalPercent_d2){
uint128 vestingSize = vestingLength;
uint128 total;
for(uint128 i=1; i<=vestingSize; i++){
Detail memory temp = vesting[i];
total += temp.ratio_d2;
if( (temp.datetime <= block.timestamp && block.timestamp <= vesting[i+1].datetime) ||
(i == vestingSize && block.timestamp >= temp.datetime)
){
round = i;
totalPercent_d2 = total;
break;
}
}
}
/**
* @dev Token claim
*/
function claimToken() external {
(uint128 round, uint128 totalPercent_d2) = vestingRunning();
Bought memory temp = invoice[msg.sender];
require(!isPaused && round > 0 && token != address(0), "!started");
require(temp.purchased > 0, "!buyer");
require(temp.completed_d2 < totalPercent_d2, "claimed");
uint128 amountToClaim;
if(temp.completed_d2 == 0){
amountToClaim = (temp.purchased * totalPercent_d2) / 10000;
} else{
amountToClaim = ((temp.claimed * totalPercent_d2) / temp.completed_d2) - temp.claimed;
}
require(IERC20(token).balanceOf(address(this)) >= amountToClaim && amountToClaim > 0, "insufficient");
invoice[msg.sender].completed_d2 = totalPercent_d2;
invoice[msg.sender].claimed = temp.claimed + amountToClaim;
TransferHelper.safeTransfer(address(token), msg.sender, amountToClaim);
}
/**
* @dev Set token project
* @param _token Token project address
*/
function _setToken(address _token) private {
token = _token;
}
/**
* @dev Insert new vestings
* @param _datetime Vesting datetime
* @param _ratio_d2 Vesting ratio in percent (decimal 2)
*/
function _newVesting(
uint128[] calldata _datetime,
uint128[] calldata _ratio_d2
) private {
require(_datetime.length == _ratio_d2.length, "!good");
uint128 vestingSize = vestingLength;
for(uint128 i=0; i<_datetime.length; i++){
if(i != _datetime.length-1) require(_datetime[i] < _datetime[i+1], "!good");
vestingSize += 1;
vesting[vestingSize] = Detail(_datetime[i], _ratio_d2[i]);
}
vestingLength = vestingSize;
}
/**
* @dev Insert new buyers & purchases
* @param _buyer Buyer address
* @param _purchased Buyer purchase
*/
function newBuyers(address[] calldata _buyer, uint128[] calldata _purchased) external onlyOwner {
require(_buyer.length == _purchased.length, "!good");
for(uint16 i=0; i<_buyer.length; i++){
if(_buyer[i] == address(0) || _purchased[i] == 0) continue;
Bought memory temp = invoice[_buyer[i]];
if(temp.purchased == 0){
buyers.push(_buyer[i]);
invoice[_buyer[i]].buyerIndex = uint128(buyers.length - 1);
}
invoice[_buyer[i]].purchased = temp.purchased + _purchased[i];
sold += _purchased[i];
}
}
/**
* @dev Replace buyers address
* @param _oldBuyer Old address
* @param _newBuyer New purchase
*/
function replaceBuyers(address[] calldata _oldBuyer, address[] calldata _newBuyer) external onlyOwner {
require(_oldBuyer.length == _newBuyer.length && buyers.length > 0, "!good");
for(uint16 i=0; i<_oldBuyer.length; i++){
Bought memory temp = invoice[_oldBuyer[i]];
if( temp.purchased == 0 ||
_oldBuyer[i] == address(0) ||
_newBuyer[i] == address(0)
) continue;
buyers[temp.buyerIndex] = _newBuyer[i];
invoice[_newBuyer[i]] = temp;
delete invoice[_oldBuyer[i]];
}
}
/**
* @dev Remove buyers
* @param _buyer Buyer address
*/
function removeBuyers(address[] calldata _buyer) external onlyOwner {
require(buyers.length > 0, "!good");
for(uint16 i=0; i<_buyer.length; i++){
Bought memory temp = invoice[_buyer[i]];
if(temp.purchased == 0 || _buyer[i] == address(0)) continue;
sold -= temp.purchased;
address addressToMove = buyers[buyers.length-1];
buyers[temp.buyerIndex] = addressToMove;
invoice[addressToMove].buyerIndex = temp.buyerIndex;
buyers.pop();
delete invoice[_buyer[i]];
}
}
/**
* @dev Replace buyers purchase
* @param _buyer Buyer address
* @param _newPurchased new purchased
*/
function replacePurchases(address[] calldata _buyer, uint128[] calldata _newPurchased) external onlyOwner {
require(_buyer.length == _newPurchased.length && buyers.length > 0, "!good");
for(uint16 i=0; i<_buyer.length; i++){
Bought memory temp = invoice[_buyer[i]];
if( temp.purchased == 0 ||
temp.completed_d2 > 0 ||
_buyer[i] == address(0) ||
_newPurchased[i] == 0) continue;
sold = sold - temp.purchased + _newPurchased[i];
invoice[_buyer[i]].purchased = _newPurchased[i];
}
}
/**
* @dev Update vestings datetime
* @param _vestingRound Vesting round
* @param _newDatetime new datetime in epoch
*/
function updateVestingDatetimes(uint128[] calldata _vestingRound, uint128[] calldata _newDatetime) external onlyOwner {
require(_vestingRound.length == _newDatetime.length, "!good");
(uint128 round, ) = vestingRunning();
uint128 vestingSize = vestingLength;
for(uint128 i=0; i<_vestingRound.length; i++){
if( _vestingRound[i] > vestingSize ||
round >= _vestingRound[i]) continue;
vesting[_vestingRound[i]].datetime = _newDatetime[i];
}
}
/**
* @dev Update vestings ratio
* @param _vestingRound Vesting round
* @param _newRatio_d2 New ratio in percent (decimal 2)
*/
function updateVestingRatios(uint128[] calldata _vestingRound, uint128[] calldata _newRatio_d2) external onlyOwner {
require(_vestingRound.length == _newRatio_d2.length, "!good");
(uint128 round, ) = vestingRunning();
uint128 vestingSize = vestingLength;
for(uint128 i=0; i<_vestingRound.length; i++){
if(_vestingRound[i] > vestingSize ||
round >= _vestingRound[i]) continue;
vesting[_vestingRound[i]].ratio_d2 = _newRatio_d2[i];
}
}
/**
* @dev Insert new vestings
* @param _datetime Vesting datetime
* @param _ratio_d2 Vesting ratio in percent (decimal 2)
*/
function newVesting(
uint128[] calldata _datetime,
uint128[] calldata _ratio_d2
) external onlyOwner {
_newVesting(_datetime, _ratio_d2);
}
/**
* @dev Remove last vesting round
*/
function removeLastVestingRound() external onlyOwner {
uint128 vestingSizeTarget = vestingLength-1;
delete vesting[vestingSizeTarget];
vestingLength = vestingSizeTarget;
}
/**
* @dev Emergency condition to withdraw token
* @param _target Target address
* @param _amount Amount to withdraw
*/
function emergencyWithdraw(address _target, uint128 _amount) external onlyOwner {
require(_target != address(0), "!good");
uint128 contractBalance = uint128(IERC20(token).balanceOf(address(this)));
if(_amount > contractBalance) _amount = contractBalance;
TransferHelper.safeTransfer(address(token), _target, _amount);
}
/**
* @dev Set token project
* @param _token Token project address
*/
function setToken(address _token) external onlyOwner {
_setToken(_token);
}
/**
* @dev Pause vesting activity
*/
function togglePause() external onlyOwner {
isPaused = !isPaused;
}
/**
* @dev Transfer ownership
* @param _newOwner New owner address
*/
function transferOwnership(address _newOwner) external onlyOwner {
require(_newOwner != address(0), "!good");
owner = _newOwner;
}
}
IFixedCreator.sol 17 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
interface IFixedCreator{
event VestingCreated(address indexed vesting, uint index);
function owner() external view returns (address);
function allVestingsLength() external view returns(uint);
function allVestings(uint) external view returns(address);
function createVesting(address, uint128[] calldata, uint128[] calldata) external returns (address);
function transferOwnership(address) external;
}
TransferHelper.sol 29 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
// helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false
library TransferHelper {
function safeApprove(address token, address to, uint value) internal {
// bytes4(keccak256(bytes("approve(address,uint256)")));
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value));
require(success && (data.length == 0 || abi.decode(data, (bool))), "TransferHelper: APPROVE_FAILED");
}
function safeTransfer(address token, address to, uint value) internal {
// bytes4(keccak256(bytes("transfer(address,uint256)")));
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));
require(success && (data.length == 0 || abi.decode(data, (bool))), "TransferHelper: TRANSFER_FAILED");
}
function safeTransferFrom(address token, address from, address to, uint value) internal {
// bytes4(keccak256(bytes("transferFrom(address,address,uint256)")));
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));
require(success && (data.length == 0 || abi.decode(data, (bool))), "TransferHelper: TRANSFER_FROM_FAILED");
}
function safeTransferETH(address to, uint value) internal {
(bool success,) = to.call{value:value}(new bytes(0));
require(success, "TransferHelper: ETH_TRANSFER_FAILED");
}
}
IERC20.sol 82 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @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);
/**
* @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);
}
Read Contract
buyers 0xf2aa8218 → address
creator 0x02d05d3f → address
getBuyerLength 0x96fe0582 → uint256
invoice 0x8f0164f6 → uint128, uint128, uint128, uint128
isPaused 0xb187bd26 → bool
owner 0x8da5cb5b → address
sold 0x02c7e7af → uint128
token 0xfc0c546a → address
vesting 0x88164468 → uint128, uint128
vestingLength 0xb217f9d4 → uint128
vestingRunning 0x084f1df5 → uint128, uint128
Write Contract 14 functions
These functions modify contract state and require a wallet transaction to execute.
claimToken 0x4451d89f
No parameters
emergencyWithdraw 0xd3b88003
address _target
uint128 _amount
initialize 0xe3083884
address _token
uint128[] _datetime
uint128[] _ratio_d2
newBuyers 0x0be86397
address[] _buyer
uint128[] _purchased
newVesting 0xc0ac5875
uint128[] _datetime
uint128[] _ratio_d2
removeBuyers 0x98b3f7e2
address[] _buyer
removeLastVestingRound 0xf33548b5
No parameters
replaceBuyers 0xa932c47a
address[] _oldBuyer
address[] _newBuyer
replacePurchases 0x545f1a2e
address[] _buyer
uint128[] _newPurchased
setToken 0x144fa6d7
address _token
togglePause 0xc4ae3168
No parameters
transferOwnership 0xf2fde38b
address _newOwner
updateVestingDatetimes 0x79d973d9
uint128[] _vestingRound
uint128[] _newDatetime
updateVestingRatios 0xf18fa08a
uint128[] _vestingRound
uint128[] _newRatio_d2
Recent Transactions
This address has 1 on-chain transactions, but only 1.1% of the chain is indexed. Transactions will appear as indexing progresses. View on Etherscan →