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.20;
interface IERC20 {
function approve(address spender, uint256 amount) external returns (bool);
function transfer(address to, uint256 value) external returns (bool);
function transferFrom(address from, address to, uint256 value) external returns (bool);
function balanceOf(address) external view returns (uint256);
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 TruthTimedSellerV3 {
// ----- constants (Uniswap V3 mainnet) -----
ISwapRouter public constant ROUTER =
ISwapRouter(0xE592427A0AEce92De3Edee1F18E0157C05861564);
// ----- immutables / storage -----
address public immutable TRUU; // TRUU token
address public STABLE; // USDT or USDC (we’ll use USDT)
address public owner; // admin
address public keeper; // allowed to trigger execute()
uint24 public poolFee; // 10000 for 1%, 3000 for 0.3%, etc.
uint256 public sellAmount; // amount of TRUU in base units (10 decimals)
uint256 public interval; // seconds between executions
uint256 public lastExec; // timestamp of last successful sell
bool public paused;
// ----- events -----
event Executed(uint256 amountIn, uint256 amountOut, uint256 when);
event Params(uint256 sellAmount, uint256 interval, uint24 fee);
event KeeperChanged(address k);
event Paused(bool p);
// ----- modifiers -----
modifier onlyOwner() {
require(msg.sender == owner, "NOT_OWNER");
_;
}
modifier onlyKeeper() {
require(msg.sender == keeper || msg.sender == owner, "NOT_KEEPER");
_;
}
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;
sellAmount = _sellAmt;
poolFee = _poolFee;
interval = _interval;
lastExec = 0;
paused = false;
// OPTIONAL: uncomment if you prefer approval in constructor
// IERC20(TRUU).approve(address(ROUTER), type(uint256).max);
emit Params(sellAmount, interval, poolFee);
emit KeeperChanged(keeper);
}
// one-time approval (call once after funding the contract with TRUU)
function approveRouter() external onlyOwner {
IERC20(TRUU).approve(address(ROUTER), type(uint256).max);
}
// manual guard for emergencies
function setPaused(bool p) external onlyOwner {
paused = p;
emit Paused(p);
}
function setKeeper(address k) external onlyOwner {
require(k != address(0), "ZERO_ADDR");
keeper = k;
emit KeeperChanged(k);
}
function setSellAmount(uint256 amt) external onlyOwner {
sellAmount = amt;
emit Params(sellAmount, interval, poolFee);
}
function setInterval(uint256 s) external onlyOwner {
interval = s;
emit Params(sellAmount, interval, poolFee);
}
function setPoolFee(uint24 f) external onlyOwner {
poolFee = f;
emit Params(sellAmount, interval, poolFee);
}
function setStable(address s) external onlyOwner {
require(s != address(0), "ZERO_ADDR");
STABLE = s;
}
// rescue tokens if needed
function sweep(address token, uint256 amount) external onlyOwner {
IERC20(token).transfer(owner, amount == 0 ? IERC20(token).balanceOf(address(this)) : amount);
}
// next allowed timestamp
function nextAllowedAt() public view returns (uint256) {
if (lastExec == 0) return 0;
unchecked { return lastExec + interval; }
}
// main execution; minOut lets you protect against bad quotes (use 0 for testing)
function execute(uint256 minOut) external onlyKeeper returns (uint256 out) {
require(!paused, "PAUSED");
require(block.timestamp >= nextAllowedAt(), "TOO_SOON");
uint256 amt = sellAmount;
require(amt > 0, "NO_SELL_AMT");
require(IERC20(TRUU).balanceOf(address(this)) >= amt, "INSUFFICIENT_TRUU");
ISwapRouter.ExactInputSingleParams memory p = ISwapRouter.ExactInputSingleParams({
tokenIn: TRUU,
tokenOut: STABLE,
fee: poolFee,
recipient: address(this),
deadline: block.timestamp + 600,
amountIn: amt,
amountOutMinimum: minOut,
sqrtPriceLimitX96: 0
});
out = ROUTER.exactInputSingle(p);
lastExec = block.timestamp;
emit Executed(amt, out, lastExec);
}
// accept ETH if any refunds come back (rare for V3 but harmless)
receive() external payable {}
}"
}
},
"settings": {
"optimizer": {
"enabled": true,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"remappings": []
}
}}
Submitted on: 2025-11-07 11:07:25
Comments
Log in to comment.
No comments yet.