diff --git a/contracts/DODOStarter/impl/FairFunding.sol b/contracts/DODOStarter/impl/FairFunding.sol index dc1e0a3..4f50861 100644 --- a/contracts/DODOStarter/impl/FairFunding.sol +++ b/contracts/DODOStarter/impl/FairFunding.sol @@ -37,6 +37,17 @@ contract FairFunding is Vesting { require(_INITIALIZED_ == false, "WE_NOT_SAVE_ETH_AFTER_INIT"); } + + // ============ Events ============ + event Settle(address indexed account); + event DepositFund(address indexed account, uint256 fundAmount); + event WithdrawFund(address indexed caller, address indexed to, uint256 fundAmount, bool isSettled); + event ClaimToken(address indexed caller, address indexed to, uint256 tokenAmount, uint256 fundAmount); + + event WithdrawUnallocatedToken(address indexed to, uint256 tokenAmount); + event InitializeLiquidity(address pool, uint256 tokenAmount); + event ClaimFund(address indexed to, uint256 fundAmount); + // ============ Init ============ function init( address[] calldata addressList, @@ -183,6 +194,8 @@ contract FairFunding is Vesting { } msg.sender.transfer(_SETTEL_FUND_); + + emit Settle(msg.sender); } // ============ Funding Functions ============ @@ -209,31 +222,43 @@ contract FairFunding is Vesting { _FUNDS_DEPOSITED_[to] = _FUNDS_DEPOSITED_[to].add(inputFund); _TOTAL_RAISED_FUNDS_ = _TOTAL_RAISED_FUNDS_.add(inputFund); + + emit DepositFund(to, inputFund); } function withdrawFunds(address to, uint256 amount) external preventReentrant { - if (!isSettled()) { + uint256 fundAmount; + bool isSettled = isSettled(); + if (!isSettled) { require(_FUNDS_DEPOSITED_[msg.sender] >= amount, "WITHDRAW_TOO_MUCH"); _FUNDS_DEPOSITED_[msg.sender] = _FUNDS_DEPOSITED_[msg.sender].sub(amount); _TOTAL_RAISED_FUNDS_ = _TOTAL_RAISED_FUNDS_.sub(amount); _FUNDS_RESERVE_ = _FUNDS_RESERVE_.sub(amount); + fundAmount = amount; IERC20(_FUNDS_ADDRESS_).safeTransfer(to, amount); } else { require(!_FUNDS_CLAIMED_[msg.sender], "ALREADY_CLAIMED"); _FUNDS_CLAIMED_[msg.sender] = true; - IERC20(_FUNDS_ADDRESS_).safeTransfer(to, getUserFundsUnused(msg.sender)); + fundAmount = getUserFundsUnused(msg.sender); + IERC20(_FUNDS_ADDRESS_).safeTransfer(to, fundAmount); } + + emit WithdrawFund(msg.sender, to, fundAmount, isSettled); } function claimToken(address to) external { require(isSettled(), "NOT_SETTLED"); uint256 totalAllocation = getUserTokenAllocation(msg.sender); - _claimToken(to, totalAllocation); + uint256 claimableTokenAmount = _claimToken(to, totalAllocation); + uint256 fundAmount = 0; if(!_FUNDS_CLAIMED_[msg.sender]) { _FUNDS_CLAIMED_[msg.sender] = true; - IERC20(_FUNDS_ADDRESS_).safeTransfer(to, getUserFundsUnused(msg.sender)); + fundAmount = getUserFundsUnused(msg.sender); + IERC20(_FUNDS_ADDRESS_).safeTransfer(to, fundAmount); } + + emit ClaimToken(msg.sender, to, claimableTokenAmount, fundAmount); } // ============ Ownable Functions ============ @@ -242,20 +267,27 @@ contract FairFunding is Vesting { require(isSettled(), "NOT_SETTLED"); require(_FINAL_PRICE_ == _LOWER_LIMIT_PRICE_, "NO_TOKEN_LEFT"); uint256 allocatedToken = DecimalMath.divCeil(_TOTAL_RAISED_FUNDS_, _FINAL_PRICE_); - IERC20(_TOKEN_ADDRESS_).safeTransfer(to, _TOTAL_TOKEN_AMOUNT_.sub(allocatedToken)); + uint256 unallocatedAmount = _TOTAL_TOKEN_AMOUNT_.sub(allocatedToken); + IERC20(_TOKEN_ADDRESS_).safeTransfer(to, unallocatedAmount); _TOTAL_TOKEN_AMOUNT_ = allocatedToken; + + emit WithdrawUnallocatedToken(to, unallocatedAmount); } function initializeLiquidity(uint256 initialTokenAmount, uint256 lpFeeRate, bool isOpenTWAP) external preventReentrant onlyOwner { require(isSettled(), "NOT_SETTLED"); uint256 totalUsedRaiseFunds = DecimalMath.mulFloor(_TOTAL_RAISED_FUNDS_, _USED_FUND_RATIO_); _initializeLiquidity(initialTokenAmount, totalUsedRaiseFunds, lpFeeRate, isOpenTWAP); + + emit InitializeLiquidity(_INITIAL_POOL_, initialTokenAmount); } function claimFund(address to) external preventReentrant onlyOwner { require(isSettled(), "NOT_SETTLED"); uint256 totalUsedRaiseFunds = DecimalMath.mulFloor(_TOTAL_RAISED_FUNDS_, _USED_FUND_RATIO_); - _claimFunds(to,totalUsedRaiseFunds); + uint256 claimableFund = _claimFunds(to,totalUsedRaiseFunds); + + emit ClaimFund(to, claimableFund); } // ============ Timeline Control Functions ============ diff --git a/contracts/DODOStarter/impl/InstantFunding.sol b/contracts/DODOStarter/impl/InstantFunding.sol index 3e7c787..735d28d 100644 --- a/contracts/DODOStarter/impl/InstantFunding.sol +++ b/contracts/DODOStarter/impl/InstantFunding.sol @@ -28,6 +28,13 @@ contract InstantFunding is Vesting { mapping(address => uint256) _TOKEN_ALLOCATION_; uint256 public _TOTAL_ALLOCATED_TOKEN_; + // ============ Events ============ + event DepositFund(address indexed account, uint256 fundAmount, uint256 allocationAmount); + event ClaimToken(address indexed caller, address indexed to, uint256 tokenAmount); + + event WithdrawUnallocatedToken(address indexed to, uint256 tokenAmount); + event InitializeLiquidity(address pool, uint256 tokenAmount); + event ClaimFund(address indexed to, uint256 fundAmount); // ============ Init ============ function init( @@ -160,12 +167,14 @@ contract InstantFunding is Vesting { uint256 currentPrice = getCurrentPrice(); newTokenAllocation = DecimalMath.divFloor(inputFund, currentPrice); + uint256 depositFundAmount = inputFund; if (newTokenAllocation.add(_TOTAL_ALLOCATED_TOKEN_) > _TOTAL_TOKEN_AMOUNT_) { newTokenAllocation = _TOTAL_TOKEN_AMOUNT_.sub(_TOTAL_ALLOCATED_TOKEN_); uint256 fundUsed = DecimalMath.mulFloor(newTokenAllocation, currentPrice); _FUNDS_USED_[to] = _FUNDS_USED_[to].add(fundUsed); _TOTAL_RAISED_FUNDS_ = _TOTAL_RAISED_FUNDS_.add(fundUsed); _FUNDS_RESERVE_ = _FUNDS_RESERVE_.add(fundUsed); + depositFundAmount = fundUsed; IERC20(_FUNDS_ADDRESS_).safeTransfer(to, inputFund.sub(fundUsed)); } else { @@ -176,28 +185,39 @@ contract InstantFunding is Vesting { _TOKEN_ALLOCATION_[to] = _TOKEN_ALLOCATION_[to].add(newTokenAllocation); _TOTAL_ALLOCATED_TOKEN_ = _TOTAL_ALLOCATED_TOKEN_.add(newTokenAllocation); + + emit DepositFund(to, depositFundAmount, newTokenAllocation); } function claimToken(address to) external { uint256 totalAllocation = getUserTokenAllocation(msg.sender); - _claimToken(to, totalAllocation); + uint256 claimableTokenAmount = _claimToken(to, totalAllocation); + + emit ClaimToken(msg.sender, to, claimableTokenAmount); } // ============ Ownable Functions ============ function withdrawUnallocatedToken(address to) external preventReentrant onlyOwner { require(isFundingEnd(), "CAN_NOT_WITHDRAW"); - IERC20(_TOKEN_ADDRESS_).safeTransfer(to, _TOTAL_TOKEN_AMOUNT_.sub(_TOTAL_ALLOCATED_TOKEN_)); + uint256 unallocatedAmount = _TOTAL_TOKEN_AMOUNT_.sub(_TOTAL_ALLOCATED_TOKEN_); + IERC20(_TOKEN_ADDRESS_).safeTransfer(to, unallocatedAmount); _TOTAL_TOKEN_AMOUNT_ = _TOTAL_ALLOCATED_TOKEN_; + + emit WithdrawUnallocatedToken(to, unallocatedAmount); } function initializeLiquidity(uint256 initialTokenAmount, uint256 lpFeeRate, bool isOpenTWAP) external preventReentrant onlyOwner { require(isFundingEnd(),"FUNDING_NOT_FINISHED"); _initializeLiquidity(initialTokenAmount, _TOTAL_RAISED_FUNDS_, lpFeeRate, isOpenTWAP); + + emit InitializeLiquidity(_INITIAL_POOL_, initialTokenAmount); } function claimFund(address to) external preventReentrant onlyOwner { - _claimFunds(to,_TOTAL_RAISED_FUNDS_); + uint256 claimableFund = _claimFunds(to,_TOTAL_RAISED_FUNDS_); + + emit ClaimFund(to, claimableFund); } // ============ Timeline Control Functions ============ diff --git a/contracts/DODOStarter/impl/Storage.sol b/contracts/DODOStarter/impl/Storage.sol index 60d093c..c558200 100644 --- a/contracts/DODOStarter/impl/Storage.sol +++ b/contracts/DODOStarter/impl/Storage.sol @@ -21,6 +21,9 @@ contract Storage is InitializableOwnable, ReentrancyGuard { bool public _FORCE_STOP_ = false; address public _QUOTA_; + // ============ Events ============ + event ForceStop(); + // ============ Token & Balance ============ uint256 public _FUNDS_RESERVE_; @@ -75,6 +78,8 @@ contract Storage is InitializableOwnable, ReentrancyGuard { _TOTAL_TOKEN_AMOUNT_ = 0; uint256 tokenAmount = IERC20(_TOKEN_ADDRESS_).balanceOf(address(this)); IERC20(_TOKEN_ADDRESS_).safeTransfer(_OWNER_, tokenAmount); + + emit ForceStop(); } function setQuota(address quota) external onlyOwner { diff --git a/contracts/DODOStarter/impl/Vesting.sol b/contracts/DODOStarter/impl/Vesting.sol index de94a4c..4853444 100644 --- a/contracts/DODOStarter/impl/Vesting.sol +++ b/contracts/DODOStarter/impl/Vesting.sol @@ -20,6 +20,9 @@ contract Vesting is Storage { using SafeMath for uint256; using SafeERC20 for IERC20; + // ============ Events ============ + event ClaimLpToken(address indexed to, uint256 lpAmount); + function claimLp(address to) external preventReentrant onlyOwner { require(_INITIAL_POOL_ != address(0), "LIQUIDITY_NOT_ESTABLISHED"); uint256 remainingLp = DecimalMath.mulFloor( @@ -30,6 +33,8 @@ contract Vesting is Storage { _CLAIMED_LP_ = _CLAIMED_LP_.add(claimableLp); IERC20(_INITIAL_POOL_).safeTransfer(to, claimableLp); + + emit ClaimLpToken(to, claimableLp); } //tokenType 0: BaseToken, 1: Fund, 2: LpToken @@ -65,24 +70,24 @@ contract Vesting is Storage { // ============ Internal Function ============ - function _claimToken(address to, uint256 totalAllocation) internal { + function _claimToken(address to, uint256 totalAllocation) internal returns(uint256 claimableTokenAmount) { uint256 remainingToken = DecimalMath.mulFloor( getRemainingRatio(block.timestamp,0), totalAllocation ); - uint256 claimableTokenAmount = totalAllocation.sub(remainingToken).sub(_CLAIMED_TOKEN_[msg.sender]); + claimableTokenAmount = totalAllocation.sub(remainingToken).sub(_CLAIMED_TOKEN_[msg.sender]); _CLAIMED_TOKEN_[msg.sender] = _CLAIMED_TOKEN_[msg.sender].add(claimableTokenAmount); IERC20(_TOKEN_ADDRESS_).safeTransfer(to,claimableTokenAmount); } - function _claimFunds(address to, uint256 totalUsedRaiseFunds) internal { + function _claimFunds(address to, uint256 totalUsedRaiseFunds) internal returns(uint256 claimableFund) { require(totalUsedRaiseFunds > _INITIAL_FUND_LIQUIDITY_, "FUND_NOT_ENOUGH"); uint256 vestingFunds = totalUsedRaiseFunds.sub(_INITIAL_FUND_LIQUIDITY_); uint256 remainingFund = DecimalMath.mulFloor( getRemainingRatio(block.timestamp,1), vestingFunds ); - uint256 claimableFund = vestingFunds.sub(remainingFund).sub(_CLAIMED_FUNDS_); + claimableFund = vestingFunds.sub(remainingFund).sub(_CLAIMED_FUNDS_); _CLAIMED_FUNDS_ = _CLAIMED_FUNDS_.add(claimableFund); IERC20(_FUNDS_ADDRESS_).safeTransfer(to, claimableFund); }