Skip to content

Instantly share code, notes, and snippets.

@alex-unicrypt
Created November 28, 2022 18:56
Show Gist options
  • Save alex-unicrypt/283d22a98fc7b66ba56cfb94db4448a4 to your computer and use it in GitHub Desktop.
Save alex-unicrypt/283d22a98fc7b66ba56cfb94db4448a4 to your computer and use it in GitHub Desktop.
This contract auto increments a preexisting Unicrypt liquidity lock using Gelato's decentralised bot network.
// SPDX-License-Identifier: MIT
// Medium Guide Gist
pragma solidity ^0.8.14;
import "@openzeppelin/contracts/access/Ownable.sol";
import "./OpsTaskCreator.sol";
interface IUniswapV2Locker {
function incrementLock(uint256 _lockID, uint256 _amount) external;
}
contract UncxAutoLocker is OpsTaskCreator, Ownable {
uint256 public gasThreshold = 80 gwei;
uint256 public lastExecuted;
bytes32 public taskId;
address public lockerAddress; // UNCX Locker Address
address public lpToken; // The LP token
uint256 public lockID; // Unicrypt liquidity lock nonce (lock ID)
uint256 public amount; // threshold token amount which triggers the Gelato increment action.
uint256 public interval = 5 minutes;
event UpdateIncrementedLock(
address locker,
address lpToken,
uint256 lockID,
uint256 amount
);
event CounterTaskCreated(bytes32 taskId);
event UpdateInterval(uint256 interval);
event UpdateGasThreshold(uint256 gasThershold);
event LockIncremented(uint256 amount);
constructor(
address _lockerAddress,
address _lpToken,
uint256 _lockID,
uint256 _amount,
address payable _ops,
address _fundsOwner
) OpsTaskCreator(_ops, _fundsOwner) {
lockerAddress = _lockerAddress;
lpToken = _lpToken;
lockID = _lockID;
amount = _amount;
lastExecuted = block.timestamp;
emit UpdateIncrementedLock(_lockerAddress, _lpToken, _lockID, _amount);
}
receive() external payable {}
function createTask() external onlyOwner {
require(taskId == bytes32(""), "Already started task");
ModuleData memory moduleData = ModuleData({
modules: new Module[](2),
args: new bytes[](2)
});
moduleData.modules[0] = Module.RESOLVER;
moduleData.modules[1] = Module.PROXY;
moduleData.args[0] = _resolverModuleArg(
address(this),
abi.encodeCall(this.checker, ())
);
moduleData.args[1] = _proxyModuleArg();
bytes32 id = _createTask(
address(this),
abi.encode(this.incrementLpLock.selector),
moduleData,
ETH
);
taskId = id;
emit CounterTaskCreated(id);
}
function incrementLpLock(uint256 _amount) external onlyDedicatedMsgSender {
SafeERC20.safeApprove(IERC20(lpToken), lockerAddress, _amount);
IUniswapV2Locker(lockerAddress).incrementLock(lockID, _amount);
(uint256 fee, address feeToken) = _getFeeDetails();
_transfer(fee, feeToken);
lastExecuted = block.timestamp;
emit LockIncremented(_amount);
}
function updateIncrementedLock(
address _lockerAddress,
address _lpToken,
uint256 _lockID,
uint256 _amount
) external onlyOwner {
lockerAddress = _lockerAddress;
lpToken = _lpToken;
lockID = _lockID;
amount = _amount;
emit UpdateIncrementedLock(_lockerAddress, _lpToken, _lockID, _amount);
}
function updateInterval(uint256 _interval) external onlyOwner {
require(_interval > 2 minutes, "Interval is too short");
interval = _interval;
emit UpdateInterval(_interval);
}
function updateGasThreshold(uint256 _gasThreshold) external onlyOwner {
gasThreshold = _gasThreshold;
emit UpdateGasThreshold(_gasThreshold);
}
function cancelTask() external onlyOwner {
_cancelTask(taskId);
taskId = bytes32("");
}
function withdrawTokens(address _token) external onlyOwner {
uint256 amountToWithdraw = IERC20(_token).balanceOf(address(this));
SafeERC20.safeApprove(IERC20(_token), owner(), amountToWithdraw);
SafeERC20.safeTransfer(IERC20(_token), owner(), amountToWithdraw);
}
function withdrawBase() external onlyOwner {
payable(msg.sender).transfer(address(this).balance);
}
function checker()
external
view
returns (bool canExec, bytes memory execPayload)
{
if (tx.gasprice > gasThreshold) {
return (false, bytes("Gas above threshold"));
}
if (IERC20(lpToken).balanceOf(address(this)) < amount) {
return (false, bytes("Amount threshold not met"));
}
canExec = (block.timestamp - lastExecuted) >= interval;
execPayload = abi.encodeWithSelector(this.incrementLpLock.selector, amount);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment