Description:
Decentralized Finance (DeFi) protocol contract providing Factory functionality.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
{{
"language": "Solidity",
"sources": {
"tru3x.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
// ---------- Interfaces ----------
interface IERC20 {
function balanceOf(address a) external view returns (uint256);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 value) external returns (bool);
function transfer(address to, uint256 value) external returns (bool);
function transferFrom(address from, address to, uint256 value) external returns (bool);
function decimals() external view returns (uint8);
}
interface ISwapRouter {
struct ExactInputSingleParams {
address tokenIn;
address tokenOut;
uint24 fee;
address recipient;
uint256 deadline;
uint256 amountIn;
uint256 amountOutMinimum;
uint160 sqrtPriceLimitX96; // set 0 for no limit
}
function exactInputSingle(ExactInputSingleParams calldata params)
external
payable
returns (uint256 amountOut);
}
// ---------- Contract ----------
contract TruthTimedSellerV3 {
// --- constants ---
// Uniswap V3 Router (Ethereum mainnet)
ISwapRouter public constant V3_ROUTER =
ISwapRouter(0xE592427A0AEce92De3Edee1F18E0157C05861564);
// --- immutables & storage ---
address public immutable OWNER; // deployer / admin
address public truu; // TRUU token (tokenIn)
address public stable; // USDT token (tokenOut)
address public keeper; // allowed caller besides OWNER
address public payee; // USDT receiver (default: OWNER)
uint256 public sellAmount; // in TRUU units (respecting TRUU decimals)
uint256 public interval; // seconds between sells (e.g. 10800 for 3h)
uint24 public poolFee; // 500, 3000, or 10000
bool public paused; // emergency stop
uint256 public lastExec; // last successful execute() timestamp
// --- events ---
event Executed(uint256 amountIn, uint256 amountOut, uint256 ts);
event ParamsUpdated(uint256 sellAmount, uint256 interval, uint24 fee, address keeper, address payee, bool paused);
event ApprovedRouter(uint256 allowance);
event Swept(address token, address to, uint256 amount);
// --- modifiers ---
modifier onlyOwner() {
require(msg.sender == OWNER, "NOT_OWNER");
_;
}
modifier onlyKeeperOrOwner() {
require(msg.sender == keeper || msg.sender == OWNER, "NOT_AUTH");
_;
}
constructor(
address _truu,
address _stable,
address _keeper,
uint256 _sellAmt,
uint24 _poolFee,
uint256 _interval
) {
require(_truu != address(0) && _stable != address(0), "ZERO_ADDR");
OWNER = msg.sender;
truu = _truu;
stable = _stable;
keeper = _keeper;
payee = msg.sender; // default: owner receives the USDT
sellAmount= _sellAmt; // e.g. 500_000 * 10**TRUU_DECIMALS
poolFee = _poolFee; // e.g. 3000 (0.3%)
interval = _interval; // e.g. 10800 (3h)
paused = false;
lastExec = 0;
emit ParamsUpdated(sellAmount, interval, poolFee, keeper, payee, paused);
}
// ---------- Admin/ops ----------
function approveRouter() external onlyOwner {
// approve max so you don't have to re-approve
uint256 max = type(uint256).max;
require(IERC20(truu).approve(address(V3_ROUTER), max), "APPROVE_FAIL");
emit ApprovedRouter(max);
}
function setParams(uint256 _sellAmt, uint256 _interval, uint24 _fee) external onlyOwner {
if (_sellAmt > 0) sellAmount = _sellAmt;
if (_interval > 0) interval = _interval;
if (_fee == 500 || _fee == 3000 || _fee == 10000) poolFee = _fee;
emit ParamsUpdated(sellAmount, interval, poolFee, keeper, payee, paused);
}
function setKeeper(address _k) external onlyOwner {
keeper = _k;
emit ParamsUpdated(sellAmount, interval, poolFee, keeper, payee, paused);
}
function setPayee(address _p) external onlyOwner {
require(_p != address(0), "ZERO_PAYEE");
payee = _p;
emit ParamsUpdated(sellAmount, interval, poolFee, keeper, payee, paused);
}
function setPaused(bool _p) external onlyOwner {
paused = _p;
emit ParamsUpdated(sellAmount, interval, poolFee, keeper, payee, paused);
}
/// Sweep any ERC20 (incl. TRUU/USDT) stuck in the contract.
function sweep(address token, address to, uint256 amount) external onlyOwner {
require(IERC20(token).transfer(to, amount), "SWEEP_FAIL");
emit Swept(token, to, amount);
}
// ---------- View helpers ----------
function nextAllowedAt() public view returns (uint256) {
return lastExec == 0 ? 0 : lastExec + interval;
}
// ---------- Core ----------
/// @notice Execute a sell if interval elapsed.
/// @param minOut USDT minimum out to protect against MEV / slippage (set 0 to skip)
function execute(uint256 minOut) external onlyKeeperOrOwner {
require(!paused, "PAUSED");
require(block.timestamp >= nextAllowedAt(), "TOO_SOON");
// check balance on contract
uint256 bal = IERC20(truu).balanceOf(address(this));
require(bal >= sellAmount, "INSUFFICIENT_TRUU");
// router must have allowance from this contract
uint256 alw = IERC20(truu).allowance(address(this), address(V3_ROUTER));
require(alw >= sellAmount, "NEED_APPROVE");
// perform V3 exactInputSingle
ISwapRouter.ExactInputSingleParams memory p = ISwapRouter.ExactInputSingleParams({
tokenIn: truu,
tokenOut: stable,
fee: poolFee,
recipient: payee, // send USDT directly to payee
deadline: block.timestamp + 300, // 5 minutes
amountIn: sellAmount,
amountOutMinimum: minOut, // set by caller (keeper/owner)
sqrtPriceLimitX96: 0 // no price limit
});
uint256 outAmt = V3_ROUTER.exactInputSingle(p);
lastExec = block.timestamp;
emit Executed(sellAmount, outAmt, lastExec);
}
}"
}
},
"settings": {
"optimizer": {
"enabled": true,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"remappings": []
}
}}
Submitted on: 2025-11-07 10:54:27
Comments
Log in to comment.
No comments yet.