// SPDX-License-Identifier: MIT// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)pragmasolidity ^0.8.0;/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/abstractcontractContext{
function_msgSender() internalviewvirtualreturns (address) {
returnmsg.sender;
}
function_msgData() internalviewvirtualreturns (bytescalldata) {
returnmsg.data;
}
}
Contract Source Code
File 2 of 9: ERC20.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/ERC20.sol)pragmasolidity ^0.8.0;import"./IERC20.sol";
import"./extensions/IERC20Metadata.sol";
import"../../utils/Context.sol";
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
* For a generic mechanism see {ERC20PresetMinterPauser}.
*
* TIP: For a detailed writeup see our guide
* https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* We have followed general OpenZeppelin Contracts guidelines: functions revert
* instead returning `false` on failure. This behavior is nonetheless
* conventional and does not conflict with the expectations of ERC20
* applications.
*
* Additionally, an {Approval} event is emitted on calls to {transferFrom}.
* This allows applications to reconstruct the allowance for all accounts just
* by listening to said events. Other implementations of the EIP may not emit
* these events, as it isn't required by the specification.
*
* Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
* functions have been added to mitigate the well-known issues around setting
* allowances. See {IERC20-approve}.
*/contractERC20isContext, IERC20, IERC20Metadata{
mapping(address=>uint256) private _balances;
mapping(address=>mapping(address=>uint256)) private _allowances;
uint256private _totalSupply;
stringprivate _name;
stringprivate _symbol;
/**
* @dev Sets the values for {name} and {symbol}.
*
* The default value of {decimals} is 18. To select a different value for
* {decimals} you should overload it.
*
* All two of these values are immutable: they can only be set once during
* construction.
*/constructor(stringmemory name_, stringmemory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev Returns the name of the token.
*/functionname() publicviewvirtualoverridereturns (stringmemory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/functionsymbol() publicviewvirtualoverridereturns (stringmemory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5.05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the value {ERC20} uses, unless this function is
* overridden;
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/functiondecimals() publicviewvirtualoverridereturns (uint8) {
return18;
}
/**
* @dev See {IERC20-totalSupply}.
*/functiontotalSupply() publicviewvirtualoverridereturns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/functionbalanceOf(address account) publicviewvirtualoverridereturns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - the caller must have a balance of at least `amount`.
*/functiontransfer(address to, uint256 amount) publicvirtualoverridereturns (bool) {
address owner = _msgSender();
_transfer(owner, to, amount);
returntrue;
}
/**
* @dev See {IERC20-allowance}.
*/functionallowance(address owner, address spender) publicviewvirtualoverridereturns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
* `transferFrom`. This is semantically equivalent to an infinite approval.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/functionapprove(address spender, uint256 amount) publicvirtualoverridereturns (bool) {
address owner = _msgSender();
_approve(owner, spender, amount);
returntrue;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {ERC20}.
*
* NOTE: Does not update the allowance if the current allowance
* is the maximum `uint256`.
*
* Requirements:
*
* - `from` and `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
* - the caller must have allowance for ``from``'s tokens of at least
* `amount`.
*/functiontransferFrom(addressfrom,
address to,
uint256 amount
) publicvirtualoverridereturns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, amount);
_transfer(from, to, amount);
returntrue;
}
/**
* @dev Atomically increases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/functionincreaseAllowance(address spender, uint256 addedValue) publicvirtualreturns (bool) {
address owner = _msgSender();
_approve(owner, spender, allowance(owner, spender) + addedValue);
returntrue;
}
/**
* @dev Atomically decreases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `spender` must have allowance for the caller of at least
* `subtractedValue`.
*/functiondecreaseAllowance(address spender, uint256 subtractedValue) publicvirtualreturns (bool) {
address owner = _msgSender();
uint256 currentAllowance = allowance(owner, spender);
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
unchecked {
_approve(owner, spender, currentAllowance - subtractedValue);
}
returntrue;
}
/**
* @dev Moves `amount` of tokens from `from` to `to`.
*
* This internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
*/function_transfer(addressfrom,
address to,
uint256 amount
) internalvirtual{
require(from!=address(0), "ERC20: transfer from the zero address");
require(to !=address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(from, to, amount);
uint256 fromBalance = _balances[from];
require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[from] = fromBalance - amount;
// Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by// decrementing then incrementing.
_balances[to] += amount;
}
emit Transfer(from, to, amount);
_afterTokenTransfer(from, to, amount);
}
/** @dev Creates `amount` tokens and assigns them to `account`, increasing
* the total supply.
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/function_mint(address account, uint256 amount) internalvirtual{
require(account !=address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply += amount;
unchecked {
// Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.
_balances[account] += amount;
}
emit Transfer(address(0), account, amount);
_afterTokenTransfer(address(0), account, amount);
}
/**
* @dev Destroys `amount` tokens from `account`, reducing the
* total supply.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
*/function_burn(address account, uint256 amount) internalvirtual{
require(account !=address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
uint256 accountBalance = _balances[account];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
unchecked {
_balances[account] = accountBalance - amount;
// Overflow not possible: amount <= accountBalance <= totalSupply.
_totalSupply -= amount;
}
emit Transfer(account, address(0), amount);
_afterTokenTransfer(account, address(0), amount);
}
/**
* @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*/function_approve(address owner,
address spender,
uint256 amount
) internalvirtual{
require(owner !=address(0), "ERC20: approve from the zero address");
require(spender !=address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
/**
* @dev Updates `owner` s allowance for `spender` based on spent `amount`.
*
* Does not update the allowance amount in case of infinite allowance.
* Revert if not enough allowance is available.
*
* Might emit an {Approval} event.
*/function_spendAllowance(address owner,
address spender,
uint256 amount
) internalvirtual{
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance !=type(uint256).max) {
require(currentAllowance >= amount, "ERC20: insufficient allowance");
unchecked {
_approve(owner, spender, currentAllowance - amount);
}
}
}
/**
* @dev Hook that is called before any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* will be transferred to `to`.
* - when `from` is zero, `amount` tokens will be minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/function_beforeTokenTransfer(addressfrom,
address to,
uint256 amount
) internalvirtual{}
/**
* @dev Hook that is called after any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* has been transferred to `to`.
* - when `from` is zero, `amount` tokens have been minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens have been burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/function_afterTokenTransfer(addressfrom,
address to,
uint256 amount
) internalvirtual{}
}
Contract Source Code
File 3 of 9: IERC20.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)pragmasolidity ^0.8.0;/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/interfaceIERC20{
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/eventTransfer(addressindexedfrom, addressindexed 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.
*/eventApproval(addressindexed owner, addressindexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/functiontotalSupply() externalviewreturns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/functionbalanceOf(address account) externalviewreturns (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.
*/functiontransfer(address to, uint256 amount) externalreturns (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.
*/functionallowance(address owner, address spender) externalviewreturns (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.
*/functionapprove(address spender, uint256 amount) externalreturns (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.
*/functiontransferFrom(addressfrom,
address to,
uint256 amount
) externalreturns (bool);
}
Contract Source Code
File 4 of 9: IERC20Metadata.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)pragmasolidity ^0.8.0;import"../IERC20.sol";
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*
* _Available since v4.1._
*/interfaceIERC20MetadataisIERC20{
/**
* @dev Returns the name of the token.
*/functionname() externalviewreturns (stringmemory);
/**
* @dev Returns the symbol of the token.
*/functionsymbol() externalviewreturns (stringmemory);
/**
* @dev Returns the decimals places of the token.
*/functiondecimals() externalviewreturns (uint8);
}
Contract Source Code
File 5 of 9: ILPDiv.sol
// SPDX-License-Identifier: MITpragmasolidity ^0.8.19;interfaceDividendPayingTokenInterface{
/// @notice View the amount of dividend in wei that an address can withdraw./// @param _owner The address of a token holder./// @return The amount of dividend in wei that `_owner` can withdraw.functiondividendOf(address _owner) externalviewreturns (uint256, uint256);
/// @notice Withdraws the ether distributed to the sender./// @dev SHOULD transfer `dividendOf(msg.sender)` wei to `msg.sender`, and `dividendOf(msg.sender)` SHOULD be 0 after the transfer./// MUST emit a `DividendWithdrawn` event if the amount of ether transferred is greater than 0.functionwithdrawDividend() external;
/// @notice View the amount of dividend in wei that an address can withdraw./// @param _owner The address of a token holder./// @return The amount of dividend in wei that `_owner` can withdraw.functionwithdrawableDividendOf(address _owner
) externalviewreturns (uint256, uint256);
/// @notice View the amount of dividend in wei that an address has withdrawn./// @param _owner The address of a token holder./// @return The amount of dividend in wei that `_owner` has withdrawn.functionwithdrawnDividendOf(address _owner
) externalviewreturns (uint256, uint256);
/// @notice View the amount of dividend in wei that an address has earned in total./// @dev accumulativeDividendOf(_owner) = withdrawableDividendOf(_owner) + withdrawnDividendOf(_owner)/// @param _owner The address of a token holder./// @return The amount of dividend in wei that `_owner` has earned in total.functionaccumulativeDividendOf(address _owner
) externalviewreturns (uint256, uint256);
/// @dev This event MUST emit when ether is distributed to token holders./// @param from The address which sends ether to this contract./// @param weiAmount The amount of distributed ether in wei.eventDividendsDistributed(addressindexedfrom, uint256 weiAmount);
/// @dev This event MUST emit when an address withdraws their dividend./// @param to The address which withdraws ether from this contract./// @param weiAmount The amount of withdrawn ether in wei.eventDividendWithdrawn(addressindexed to, uint256 weiAmount);
}
Contract Source Code
File 6 of 9: LPDiv.sol
// SPDX-License-Identifier: MITpragmasolidity ^0.8.19;import"@openzeppelin/contracts/utils/Context.sol";
import"@openzeppelin/contracts/access/Ownable.sol";
import"@openzeppelin/contracts/token/ERC20/ERC20.sol";
import"@openzeppelin/contracts/token/ERC20/IERC20.sol";
import"./libraries/SafeMath.sol";
import"./interfaces/ILPDiv.sol";
interfaceIPair{
functiongetReserves()
externalviewreturns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
functiontoken0() externalviewreturns (address);
}
interfaceIFactory{
functioncreatePair(address tokenA,
address tokenB
) externalreturns (address pair);
functiongetPair(address tokenA,
address tokenB
) externalviewreturns (address pair);
}
interfaceIUniswapRouter{
functionfactory() externalpurereturns (address);
functionWETH() externalpurereturns (address);
functionaddLiquidityETH(address token,
uint amountTokenDesired,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
)
externalpayablereturns (uint amountToken, uint amountETH, uint liquidity);
functionswapExactTokensForTokensSupportingFeeOnTransferTokens(uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
functionswapExactETHForTokens(uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) externalpayablereturns (uint[] memory amounts);
functionswapExactTokensForETHSupportingFeeOnTransferTokens(uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
}
contractDividendPayingTokenisERC20, DividendPayingTokenInterface, Ownable{
usingSafeMathforuint256;
usingSafeMathUintforuint256;
usingSafeMathIntforint256;
addresspublic lpToken;
addresspublic platformToken;
// With `magnitude`, we can properly distribute dividends even if the amount of received ether is small.// For more discussion about choosing the value of `magnitude`,// see https://github.com/ethereum/EIPs/issues/1726#issuecomment-472352728uint256internalconstant magnitude =2**128;
uint256internal MagnifiedDividendPerShareLP;
uint256internal MagnifiedDividendPerShareToken;
// About dividendCorrection:// If the token balance of a `_user` is never changed, the dividend of `_user` can be computed with:// `dividendOf(_user) = dividendPerShare * balanceOf(_user)`.// When `balanceOf(_user)` is changed (via minting/burning/transferring tokens),// `dividendOf(_user)` should not be changed,// but the computed value of `dividendPerShare * balanceOf(_user)` is changed.// To keep the `dividendOf(_user)` unchanged, we add a correction term:// `dividendOf(_user) = dividendPerShare * balanceOf(_user) + dividendCorrectionOf(_user)`,// where `dividendCorrectionOf(_user)` is updated whenever `balanceOf(_user)` is changed:// `dividendCorrectionOf(_user) = dividendPerShare * (old balanceOf(_user)) - (new balanceOf(_user))`.// So now `dividendOf(_user)` returns the same value before and after `balanceOf(_user)` is changed.mapping(address=>int256) internal magnifiedDividendCorrectionsLP;
mapping(address=>int256) internal magnifiedDividendCorrectionsToken;
mapping(address=>uint256) internal withdrawnDividendsLP;
mapping(address=>uint256) internal withdrawnDividendsToken;
uint256public totalDividendsDistributedLP;
uint256public totalDividendsDistributedToken;
uint256public totalDividendsWithdrawnLP;
uint256public totalDividendsWithdrawnToken;
constructor(stringmemory _name,
stringmemory _symbol
) ERC20(_name, _symbol) {}
functiondistributeDividends(uint256 amountLP, uint256 amountToken) publiconlyOwner{
require(totalSupply() >0, "Total supply must be greater than zero");
if (amountLP >0) {
MagnifiedDividendPerShareLP = MagnifiedDividendPerShareLP.add(
(amountLP).mul(magnitude) / totalSupply()
);
emit DividendsDistributed(msg.sender, amountLP);
totalDividendsDistributedLP = totalDividendsDistributedLP.add(amountLP);
}
if (amountToken >0) {
MagnifiedDividendPerShareToken = MagnifiedDividendPerShareToken.add(
(amountToken).mul(magnitude) / totalSupply()
);
emit DividendsDistributed(msg.sender, amountToken);
totalDividendsDistributedToken = totalDividendsDistributedToken.add(amountToken);
}
}
/// @notice Withdraws the ether distributed to the sender./// @dev It emits a `DividendWithdrawn` event if the amount of withdrawn ether is greater than 0.functionwithdrawDividend() public// virtual override {
_withdrawDividendOfUser(msg.sender);
}
/// @notice Withdraws the ether distributed to the sender./// @dev It emits a `DividendWithdrawn` event if the amount of withdrawn ether is greater than 0.function_withdrawDividendOfUser(address user
) internalreturns (uint256, uint256) {
uint256 withdrawableLP;
uint256 withdrawableToken;
(uint256 _withdrawableDividendLP, uint256 _withdrawableDividendToken) = withdrawableDividendOf(user);
if (_withdrawableDividendLP >0) {
withdrawnDividendsLP[user] = withdrawnDividendsLP[user].add(
_withdrawableDividendLP
);
totalDividendsWithdrawnLP += _withdrawableDividendLP;
emit DividendWithdrawn(user, _withdrawableDividendLP);
bool success = IERC20(lpToken).transfer(
user,
_withdrawableDividendLP
);
if (!success) {
withdrawnDividendsLP[user] = withdrawnDividendsLP[user].sub(
_withdrawableDividendLP
);
totalDividendsWithdrawnLP -= _withdrawableDividendLP;
} else {
withdrawableLP = _withdrawableDividendLP;
}
}
if (_withdrawableDividendToken >0) {
withdrawnDividendsToken[user] = withdrawnDividendsToken[user].add(
_withdrawableDividendToken
);
totalDividendsWithdrawnToken += _withdrawableDividendToken;
emit DividendWithdrawn(user, _withdrawableDividendToken);
bool success = IERC20(platformToken).transfer(
user,
_withdrawableDividendToken
);
if (!success) {
withdrawnDividendsToken[user] = withdrawnDividendsToken[user].sub(
_withdrawableDividendToken
);
totalDividendsWithdrawnToken -= _withdrawableDividendToken;
} else {
withdrawableToken = _withdrawableDividendToken;}
}
return (withdrawableLP, withdrawableToken);
}
/// @notice View the amount of dividend in wei that an address can withdraw./// @param _owner The address of a token holder./// @return The amount of dividend in wei that `_owner` can withdraw.functiondividendOf(address _owner) publicviewoverridereturns (uint256, uint256) {
return withdrawableDividendOf(_owner);
}
/// @notice View the amount of dividend in wei that an address can withdraw./// @param _owner The address of a token holder./// @return The amount of dividend in wei that `_owner` can withdraw.functionwithdrawableDividendOf(address _owner
) publicviewoverridereturns (uint256, uint256) {
(uint256 dividendOfLP, uint256 dividendOfShareToken) = accumulativeDividendOf(_owner);
return (dividendOfLP.sub(withdrawnDividendsLP[_owner]),
dividendOfShareToken.sub(withdrawnDividendsToken[_owner])
);
}
/// @notice View the amount of dividend in wei that an address has withdrawn./// @param _owner The address of a token holder./// @return The amount of dividend in wei that `_owner` has withdrawn.functionwithdrawnDividendOf(address _owner
) publicviewoverridereturns (uint256, uint256) {
return (withdrawnDividendsLP[_owner], withdrawnDividendsToken[_owner]);
}
/// @notice View the amount of dividend in wei that an address has earned in total./// @dev accumulativeDividendOf(_owner) = withdrawableDividendOf(_owner) + withdrawnDividendOf(_owner)/// = (magnifiedDividendPerShare * balanceOf(_owner) + magnifiedDividendCorrections[_owner]) / magnitude/// @param _owner The address of a token holder./// @return The amount of dividend in wei that `_owner` has earned in total.functionaccumulativeDividendOf(address _owner
) publicviewoverridereturns (uint256, uint256) {
uint256 lpShare =
MagnifiedDividendPerShareLP
.mul(balanceOf(_owner))
.toInt256Safe()
.add(magnifiedDividendCorrectionsLP[_owner])
.toUint256Safe() / magnitude;
uint256 tokenShare =
MagnifiedDividendPerShareToken
.mul(balanceOf(_owner))
.toInt256Safe()
.add(magnifiedDividendCorrectionsToken[_owner])
.toUint256Safe() / magnitude;
return (lpShare, tokenShare);
}
/// @dev Internal function that transfer tokens from one address to another./// Update magnifiedDividendCorrections to keep dividends unchanged./// @param from The address to transfer from./// @param to The address to transfer to./// @param value The amount to be transferred.function_transfer(addressfrom,
address to,
uint256 value
) internalvirtualoverride{
require(false);
int256 _magCorrection = MagnifiedDividendPerShareLP
.mul(value)
.toInt256Safe();
magnifiedDividendCorrectionsLP[from] = magnifiedDividendCorrectionsLP[from]
.add(_magCorrection);
magnifiedDividendCorrectionsLP[to] = magnifiedDividendCorrectionsLP[to].sub(
_magCorrection
);
int256 _magCorrectionToken = MagnifiedDividendPerShareToken
.mul(value)
.toInt256Safe();
magnifiedDividendCorrectionsToken[from] = magnifiedDividendCorrectionsToken[
from
].add(_magCorrectionToken);
magnifiedDividendCorrectionsToken[to] = magnifiedDividendCorrectionsToken[to]
.sub(_magCorrectionToken);
}
/// @dev Internal function that mints tokens to an account./// Update magnifiedDividendCorrections to keep dividends unchanged./// @param account The account that will receive the created tokens./// @param value The amount that will be created.function_mint(address account, uint256 value) internaloverride{
super._mint(account, value);
magnifiedDividendCorrectionsLP[account] = magnifiedDividendCorrectionsLP[
account
].sub((MagnifiedDividendPerShareLP.mul(value)).toInt256Safe());
magnifiedDividendCorrectionsToken[account] = magnifiedDividendCorrectionsToken[
account
].sub((MagnifiedDividendPerShareToken.mul(value)).toInt256Safe());
}
/// @dev Internal function that burns an amount of the token of a given account./// Update magnifiedDividendCorrections to keep dividends unchanged./// @param account The account whose tokens will be burnt./// @param value The amount that will be burnt.function_burn(address account, uint256 value) internaloverride{
super._burn(account, value);
magnifiedDividendCorrectionsLP[account] = magnifiedDividendCorrectionsLP[
account
].add((MagnifiedDividendPerShareLP.mul(value)).toInt256Safe());
magnifiedDividendCorrectionsToken[account] = magnifiedDividendCorrectionsToken[
account
].add((MagnifiedDividendPerShareToken.mul(value)).toInt256Safe());
}
function_setBalance(address account, uint256 newBalance) internal{
uint256 currentBalance = balanceOf(account);
if (newBalance > currentBalance) {
uint256 mintAmount = newBalance.sub(currentBalance);
_mint(account, mintAmount);
} elseif (newBalance < currentBalance) {
uint256 burnAmount = currentBalance.sub(newBalance);
_burn(account, burnAmount);
}
}
}
Contract Source Code
File 7 of 9: Ownable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)pragmasolidity ^0.8.0;import"../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/abstractcontractOwnableisContext{
addressprivate _owner;
eventOwnershipTransferred(addressindexed previousOwner, addressindexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/modifieronlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/functionowner() publicviewvirtualreturns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/function_checkOwner() internalviewvirtual{
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/functionrenounceOwnership() publicvirtualonlyOwner{
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/functiontransferOwnership(address newOwner) publicvirtualonlyOwner{
require(newOwner !=address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/function_transferOwnership(address newOwner) internalvirtual{
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
Contract Source Code
File 8 of 9: SafeMath.sol
// SPDX-License-Identifier: MITpragmasolidity ^0.8.19;librarySafeMath{
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/functionadd(uint256 a, uint256 b) internalpurereturns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/functionsub(uint256 a, uint256 b) internalpurereturns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/functionsub(uint256 a,
uint256 b,
stringmemory errorMessage
) internalpurereturns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/functionmul(uint256 a, uint256 b) internalpurereturns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the// benefit is lost if 'b' is also tested.// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522if (a ==0) {
return0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/functiondiv(uint256 a, uint256 b) internalpurereturns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/functiondiv(uint256 a,
uint256 b,
stringmemory errorMessage
) internalpurereturns (uint256) {
require(b >0, errorMessage);
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't holdreturn c;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/functionmod(uint256 a, uint256 b) internalpurereturns (uint256) {
return mod(a, b, "SafeMath: modulo by zero");
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts with custom message when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/functionmod(uint256 a,
uint256 b,
stringmemory errorMessage
) internalpurereturns (uint256) {
require(b !=0, errorMessage);
return a % b;
}
}
/**
* @title SafeMathInt
* @dev Math operations for int256 with overflow safety checks.
*/librarySafeMathInt{
int256privateconstant MIN_INT256 =int256(1) <<255;
int256privateconstant MAX_INT256 =~(int256(1) <<255);
/**
* @dev Multiplies two int256 variables and fails on overflow.
*/functionmul(int256 a, int256 b) internalpurereturns (int256) {
int256 c = a * b;
// Detect overflow when multiplying MIN_INT256 with -1require(c != MIN_INT256 || (a & MIN_INT256) != (b & MIN_INT256));
require((b ==0) || (c / b == a));
return c;
}
/**
* @dev Division of two int256 variables and fails on overflow.
*/functiondiv(int256 a, int256 b) internalpurereturns (int256) {
// Prevent overflow when dividing MIN_INT256 by -1require(b !=-1|| a != MIN_INT256);
// Solidity already throws when dividing by 0.return a / b;
}
/**
* @dev Subtracts two int256 variables and fails on overflow.
*/functionsub(int256 a, int256 b) internalpurereturns (int256) {
int256 c = a - b;
require((b >=0&& c <= a) || (b <0&& c > a));
return c;
}
/**
* @dev Adds two int256 variables and fails on overflow.
*/functionadd(int256 a, int256 b) internalpurereturns (int256) {
int256 c = a + b;
require((b >=0&& c >= a) || (b <0&& c < a));
return c;
}
/**
* @dev Converts to absolute value, and fails on overflow.
*/functionabs(int256 a) internalpurereturns (int256) {
require(a != MIN_INT256);
return a <0 ? -a : a;
}
functiontoUint256Safe(int256 a) internalpurereturns (uint256) {
require(a >=0);
returnuint256(a);
}
}
/**
* @title SafeMathUint
* @dev Math operations with safety checks that revert on error
*/librarySafeMathUint{
functiontoInt256Safe(uint256 a) internalpurereturns (int256) {
int256 b =int256(a);
require(b >=0);
return b;
}
}
Contract Source Code
File 9 of 9: Trident.sol
// SPDX-License-Identifier: MIT/*
Website: https://tridentdefi.io/
Telegram: https://t.me/TriDefiErc
Twitter: https://x.com/TriDefiErc
*/pragmasolidity ^0.8.19;import"./LPDiv.sol";
contractTridentisERC20, Ownable{
IUniswapRouter public router;
addresspublic pair;
uint256publicconstant EPOCH_DURATION =3600;
uint256public startTimestamp;
enumEpoch { First, Second, Third }
boolprivate swapping;
boolpublic swapEnabled =true;
boolpublic claimEnabled =true;
boolpublic tradingEnabled;
DividendTracker public dividendTracker;
addresspublic devWallet;
uint256public swapTokensAtAmount;
uint256public maxBuyAmount;
uint256public maxSellAmount;
uint256public maxWallet;
uint256 buyLiquidityTax =3; // 3%uint256 buyDevTax =2; // 2%uint256 sellLiquidityTax =3;
uint256 sellDevTax =2;
uint256public totalBuyTax =5;
uint256public totalSellTax =5;
mapping(address=>bool) private _isExcludedFromFees;
mapping(address=>bool) public automatedMarketMakerPairs;
mapping(address=>bool) private _isExcludedFromMaxWallet;
// EventseventExcludeFromFees(addressindexed account, bool isExcluded);
eventExcludeMultipleAccountsFromFees(address[] accounts, bool isExcluded);
eventSetAutomatedMarketMakerPair(addressindexed pair, boolindexed value);
eventGasForProcessingUpdated(uint256indexed newValue,
uint256indexed oldValue
);
eventSendDividends(uint256 tokensSwapped, uint256 amount);
eventProcessedDividendTracker(uint256 iterations,
uint256 claims,
uint256 lastProcessedIndex,
boolindexed automatic,
uint256 gas,
addressindexed processor
);
constructor() ERC20("Trident DeFi", "TRI") {
dividendTracker =new DividendTracker("TRI_Dividend_Tracker", "TRI_Dividend_Tracker");
setDevWallet(0x116127e0000A3Ba1949E416C55304582431b830B);
IUniswapRouter _router = IUniswapRouter(
0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D
);
address _pair = IFactory(_router.factory()).createPair(
address(this),
_router.WETH()
);
startTimestamp =block.timestamp;
router = _router;
pair = _pair;
setSwapTokensAtAmount(2400);
updateMaxWalletAmount(30000);
setMaxBuyAndSell(30000, 30000);
_setAutomatedMarketMakerPair(_pair, true);
dividendTracker.updateLP_Token(pair, address(this));
dividendTracker.excludeFromDividends(address(dividendTracker), true);
dividendTracker.excludeFromDividends(address(this), true);
dividendTracker.excludeFromDividends(owner(), true);
dividendTracker.excludeFromDividends(address(0xdead), true);
dividendTracker.excludeFromDividends(address(0), true);
dividendTracker.excludeFromDividends(address(_router), true);
excludeFromMaxWallet(address(_pair), true);
excludeFromMaxWallet(address(this), true);
excludeFromMaxWallet(address(_router), true);
excludeFromMaxWallet(address(dividendTracker), true);
excludeFromMaxWallet(address(0xdead), true);
excludeFromFees(owner(), true);
excludeFromFees(address(this), true);
excludeFromFees(address(dividendTracker), true);
excludeFromFees(address(0xdead), true);
_mint(owner(), 3000000* (10**18));
}
receive() externalpayable{}
functionupdateLPDividendTracker(address newAddress) publiconlyOwner{
DividendTracker newDividendTracker = DividendTracker(
newAddress
);
newDividendTracker.excludeFromDividends(
address(newDividendTracker),
true
);
newDividendTracker.excludeFromDividends(address(this), true);
newDividendTracker.excludeFromDividends(owner(), true);
newDividendTracker.excludeFromDividends(address(router), true);
dividendTracker.excludeFromDividends(address(0), true);
dividendTracker = newDividendTracker;
}
/// @notice Manual claim the dividendsfunctionclaimDividend() external{
require(claimEnabled, "Claim not enabled");
dividendTracker.processAccount(msg.sender);
}
functionupdateMaxWalletAmount(uint256 newNum) publiconlyOwner{
maxWallet = newNum *10**18;
}
functionsetMaxBuyAndSell(uint256 maxBuy,
uint256 maxSell
) publiconlyOwner{
maxBuyAmount = maxBuy *10**18;
maxSellAmount = maxSell *10**18;
}
functionsetSwapTokensAtAmount(uint256 amount) publiconlyOwner{
swapTokensAtAmount = amount *10**18;
}
functionexcludeFromMaxWallet(address account,
bool excluded
) publiconlyOwner{
_isExcludedFromMaxWallet[account] = excluded;
}
/// @notice Withdraw tokens sent by mistake./// @param tokenAddress The address of the token to withdrawfunctionrescueETH20Tokens(address tokenAddress) externalonlyOwner{
IERC20(tokenAddress).transfer(
owner(),
IERC20(tokenAddress).balanceOf(address(this))
);
}
/// @notice Send remaining ETH to dev/// @dev It will send all ETH to devfunctionforceSend() externalonlyOwner{
uint256 ETHbalance =address(this).balance;
(bool success, ) =payable(devWallet).call{value: ETHbalance}("");
require(success);
}
functiontrackerRescueETH20Tokens(address tokenAddress) externalonlyOwner{
dividendTracker.trackerRescueETH20Tokens(msg.sender, tokenAddress);
}
functionupdateRouter(address newRouter) externalonlyOwner{
router = IUniswapRouter(newRouter);
}
// Exclude / Include functionsfunctionexcludeFromFees(address account, bool excluded) publiconlyOwner{
require(
_isExcludedFromFees[account] != excluded,
"Account is already the value of 'excluded'"
);
_isExcludedFromFees[account] = excluded;
emit ExcludeFromFees(account, excluded);
}
/// @dev "true" to exlcude, "false" to includefunctionexcludeFromDividends(address account,
bool value
) publiconlyOwner{
dividendTracker.excludeFromDividends(account, value);
}
functionsetDevWallet(address newWallet) publiconlyOwner{
devWallet = newWallet;
}
functionsetBuyTaxes(uint256 _liquidity,
uint256 _dev
) externalonlyOwner{
require(_liquidity + _dev <=35, "Fee must be <= 35%");
buyLiquidityTax = _liquidity;
buyDevTax = _dev;
totalBuyTax = _liquidity + _dev;
}
functionsetSellTaxes(uint256 _liquidity,
uint256 _dev
) externalonlyOwner{
require(_liquidity + _dev <=35, "Fee must be <= 35%");
sellLiquidityTax = _liquidity;
sellDevTax = _dev;
totalSellTax = _liquidity + _dev;
}
/// @notice Enable or disable internal swaps/// @dev Set "true" to enable internal swaps for liquidity, treasury and dividendsfunctionsetSwapEnabled(bool _enabled) externalonlyOwner{
swapEnabled = _enabled;
}
functionenableTrading() externalonlyOwner{
require(!tradingEnabled, "Trading already enabled");
tradingEnabled =true;
}
functionsetClaimEnabled(bool state) externalonlyOwner{
claimEnabled = state;
}
/// @dev Set new pairs created due to listing in new DEXfunctionsetAutomatedMarketMakerPair(address newPair,
bool value
) externalonlyOwner{
_setAutomatedMarketMakerPair(newPair, value);
}
function_setAutomatedMarketMakerPair(address newPair, bool value) private{
require(
automatedMarketMakerPairs[newPair] != value,
"Automated market maker pair is already set to that value"
);
automatedMarketMakerPairs[newPair] = value;
if (value) {
dividendTracker.excludeFromDividends(newPair, true);
}
emit SetAutomatedMarketMakerPair(newPair, value);
}
functiongetTotalDividendsDistributed() externalviewreturns (uint256, uint256) {
return (dividendTracker.totalDividendsDistributedLP(), dividendTracker.totalDividendsDistributedToken());
}
functionisExcludedFromFees(address account) publicviewreturns (bool) {
return _isExcludedFromFees[account];
}
functionwithdrawableDividendOf(address account
) publicviewreturns (uint256, uint256) {
return dividendTracker.withdrawableDividendOf(account);
}
functiondividendTokenBalanceOf(address account
) publicviewreturns (uint256) {
return dividendTracker.balanceOf(account);
}
functiongetAccountInfo(address account
) externalviewreturns (address, uint256, uint256, uint256, uint256, uint256, uint256) {
return dividendTracker.getAccount(account);
}
function_transfer(addressfrom,
address to,
uint256 amount
) internaloverride{
require(from!=address(0), "ERC20: transfer from the zero address");
require(to !=address(0), "ERC20: transfer to the zero address");
if (
!_isExcludedFromFees[from] &&!_isExcludedFromFees[to] &&!swapping
) {
require(tradingEnabled, "Trading not active");
if (automatedMarketMakerPairs[to]) {
require(
amount <= maxSellAmount,
"You are exceeding maxSellAmount"
);
} elseif (automatedMarketMakerPairs[from])
require(
amount <= maxBuyAmount,
"You are exceeding maxBuyAmount"
);
if (!_isExcludedFromMaxWallet[to]) {
require(
amount + balanceOf(to) <= maxWallet,
"Unable to exceed Max Wallet"
);
}
}
if (amount ==0) {
super._transfer(from, to, 0);
return;
}
uint256 contractTokenBalance = balanceOf(address(this));
bool canSwap = contractTokenBalance >= swapTokensAtAmount;
if (
canSwap &&!swapping &&
swapEnabled &&
automatedMarketMakerPairs[to] &&!_isExcludedFromFees[from] &&!_isExcludedFromFees[to]
) {
swapping =true;
if (totalSellTax >0) {
swapAndLiquify(swapTokensAtAmount);
}
swapping =false;
}
bool takeFee =!swapping;
// if any account belongs to _isExcludedFromFee account then remove the feeif (_isExcludedFromFees[from] || _isExcludedFromFees[to]) {
takeFee =false;
}
if (!automatedMarketMakerPairs[to] &&!automatedMarketMakerPairs[from])
takeFee =false;
if (takeFee) {
uint256 feeAmt;
if (automatedMarketMakerPairs[to])
feeAmt = (amount * totalSellTax) /100;
elseif (automatedMarketMakerPairs[from])
feeAmt = (amount * totalBuyTax) /100;
amount = amount - feeAmt;
super._transfer(from, address(this), feeAmt);
}
super._transfer(from, to, amount);
try dividendTracker.setBalance(from, balanceOf(from)) {} catch {}
try dividendTracker.setBalance(to, balanceOf(to)) {} catch {}
}
functionswapAndLiquify(uint256 tokens) private{
uint256 contractBalance = balanceOf(address(this));
uint256 totalTokens = tokens;
if (contractBalance ==0|| totalTokens ==0) {
return;
}
if (contractBalance > totalTokens *15) {
totalTokens *=15;
}
uint256 tokensForDividends = ((totalTokens * sellLiquidityTax) /
totalSellTax);
uint256 toSwapForDev = (totalTokens * sellDevTax) / totalSellTax;
if(getCurrentEpoch() == Epoch.First) {
tokensForDividends /=2;
swapTokensForETH(tokensForDividends);
uint256 currentbalance =address(this).balance;
if (currentbalance >0) {
// Add liquidity to uni
addLiquidity(tokensForDividends, currentbalance);
}
uint256 lpBalance = IERC20(pair).balanceOf(address(this));
//Send LP to dividendsuint256 lpDividends = lpBalance;
if (lpDividends >0) {
bool success = IERC20(pair).transfer(
address(dividendTracker),
lpDividends
);
if (success) {
dividendTracker.distributeDividends(lpDividends, 0);
emit SendDividends(tokens, lpDividends);
}
}
}
if(getCurrentEpoch() == Epoch.Second) {
_transfer(
address(this),
address(dividendTracker),
tokensForDividends
);
dividendTracker.distributeDividends(0, tokensForDividends);
emit SendDividends(tokens, tokensForDividends);
}
if(getCurrentEpoch() == Epoch.Third) {
_transfer(address(this), address(0xdead), tokensForDividends);
}
swapTokensForETH(toSwapForDev);
uint256 EthTaxBalance =address(this).balance;
// Send ETH to devuint256 devAmt = EthTaxBalance;
if (devAmt >0) {
(bool success, ) =payable(devWallet).call{value: devAmt}("");
require(success, "Failed to send ETH to dev wallet");
}
}
// transfers Dividend from the owners wallet to holders // must approve this contract, on pair contract before callingfunctionManualLPDividendDistribution(uint256 amount) publiconlyOwner{
bool success = IERC20(pair).transferFrom(
msg.sender,
address(dividendTracker),
amount
);
if (success) {
dividendTracker.distributeDividends(amount, 0);
}
}
// transfers Dividend from the owners wallet to holders // must approve this contract, on pair contract before callingfunctionManualTokenDividendDistribution(uint256 amount) publiconlyOwner{
bool success = transferFrom(
msg.sender,
address(dividendTracker),
amount
);
if (success) {
dividendTracker.distributeDividends(0, amount);
}
}
functionswapTokensForETH(uint256 tokenAmount) private{
address[] memory path =newaddress[](2);
path[0] =address(this);
path[1] = router.WETH();
_approve(address(this), address(router), tokenAmount);
// make the swap
router.swapExactTokensForETHSupportingFeeOnTransferTokens(
tokenAmount,
0, // accept any amount of ETH
path,
address(this),
block.timestamp
);
}
functiongetCurrentEpoch() publicviewreturns (Epoch) {
uint256 timeElapsed =block.timestamp- startTimestamp;
uint256 epochIndex = (timeElapsed / EPOCH_DURATION) %3;
if (epochIndex ==0) {
return Epoch.First;
} elseif (epochIndex ==1) {
return Epoch.Second;
} else {
return Epoch.Third;
}
}
functionaddLiquidity(uint256 tokenAmount, uint256 ethAmount) private{
// approve token transfer to cover all possible scenarios
_approve(address(this), address(router), tokenAmount);
// add the liquidity
router.addLiquidityETH{value: ethAmount}(
address(this),
tokenAmount,
0, // slippage is unavoidable0, // slippage is unavoidableaddress(this),
block.timestamp
);
}
}
contractDividendTrackerisOwnable, DividendPayingToken{
structAccountInfo {
address account;
uint256 withdrawableDividendsLP;
uint256 withdrawableDividendsToken;
uint256 totalDividendsLP;
uint256 totalDividendsToken;
uint256 lastClaimTimeLP;
uint256 lastClaimTimeToken;
}
mapping(address=>bool) public excludedFromDividends;
mapping(address=>uint256) public lastClaimTimesLP;
mapping(address=>uint256) public lastClaimTimesToken;
eventExcludeFromDividends(addressindexed account, bool value);
eventClaim(addressindexed account, uint256 amount);
constructor(stringmemory name, stringmemory symbol)
DividendPayingToken(
name,
symbol
)
{}
functiontrackerRescueETH20Tokens(address recipient,
address tokenAddress
) externalonlyOwner{
IERC20(tokenAddress).transfer(
recipient,
IERC20(tokenAddress).balanceOf(address(this))
);
}
functionupdateLP_Token(address _divToken, address token) externalonlyOwner{
lpToken = _divToken;
platformToken = token;
}
function_transfer(address, address, uint256) internalpureoverride{
require(false, "TRI_Dividend_Tracker: No transfers allowed");
}
functionexcludeFromDividends(address account,
bool value
) externalonlyOwner{
require(excludedFromDividends[account] != value);
excludedFromDividends[account] = value;
if (value ==true) {
_setBalance(account, 0);
} else {
_setBalance(account, balanceOf(account));
}
emit ExcludeFromDividends(account, value);
}
functiongetAccount(address account
) publicviewreturns (address, uint256, uint256, uint256, uint256, uint256, uint256) {
AccountInfo memory info;
info.account = account;
(info.withdrawableDividendsLP, info.withdrawableDividendsLP) = withdrawableDividendOf(account);
(info.totalDividendsLP, info.totalDividendsToken) = accumulativeDividendOf(account);
info.lastClaimTimeLP = lastClaimTimesLP[account];
info.lastClaimTimeToken = lastClaimTimesToken[account];
return (
info.account,
info.withdrawableDividendsLP,
info.withdrawableDividendsLP,
info.lastClaimTimeLP,
info.lastClaimTimeToken,
totalDividendsWithdrawnLP,
totalDividendsWithdrawnToken
);
}
functionsetBalance(address account,
uint256 newBalance
) externalonlyOwner{
if (excludedFromDividends[account]) {
return;
}
_setBalance(account, newBalance);
}
functionprocessAccount(address account
) externalonlyOwnerreturns (bool) {
(uint256 amountLP, uint256 amountToken) = _withdrawDividendOfUser(account);
if (amountLP >0) {
lastClaimTimesLP[account] =block.timestamp;
emit Claim(account, amountLP);
returntrue;
}
if (amountToken >0) {
lastClaimTimesToken[account] =block.timestamp;
emit Claim(account, amountToken);
returntrue;
}
returntrue;
}
}