0

I want to create a time-based upkeep directly from my contract. I was able to register and fund the upkeep but for some reason the function is not getting executed automatically. Here's the code `

// Goerli network
address public cronFactoryAddress = 0x1af3cE8de065774B0EC08942FC5779930d1A9622;
address public keeperRegistrar = 0x57A4a13b35d25EE78e084168aBaC5ad360252467;

constructor(){
        cronFactory = ICronFactory(cronFactoryAddress);
    }

function createUpkeep(string memory _cronString) public{
        address _target = address(this);    
        bytes memory functionToCall = bytes(abi.encodeWithSignature("sendSalary(string)", _cronString));
        
        bytes memory job = cronFactory.encodeCronJob(_target, functionToCall,  _cronString);
        uint256 maxJobs = cronFactory.s_maxJobs();
        address delegateAddress = cronFactory.cronDelegateAddress();
        address newCronUpkeep = address(new CronUpkeep(msg.sender, delegateAddress, maxJobs, job));
        allUpkeeps.push(newCronUpkeep);
    }

function fundUpkeep(uint256 _linkAmount, address _upkeepAddress) public{
        bytes4 reg = bytes4(keccak256("register(string,bytes,address,uint32,address,bytes,bytes,uint96,address)"));
        bytes memory _data = abi.encode(
            "TestV2",
            "",
            _upkeepAddress,
            uint32(500000),
            address(this),
            "",
            "",
            _linkAmount,
            address(this)
        );
        bytes memory combinedData = abi.encodePacked(reg, _data);
        LinkContract.transferAndCall(keeperRegistrar, _linkAmount, combinedData);
    }

sendSalary is the function in my contract that I want to be executed at regular intervals.
cronFactory is the cron factory contract.
cronUpkeep is the cronUpkeep.sol contract from the chainlink github repo.

To create these functions, I created a time-based upkeep manually and used the transaction logs to find what all function are being called and implemented the same here.

But, Once I execute both these functions nothing happens, however, I am able to find the upkeep registered on chainlink's website . And also it shows the trigger as custom trigger on upkeep page on chainlink:

chanlink upkeep

Please let me know how I can solve this? Any help would be appreciated. Thanks in advance

Aashar
  • 1
  • 1
  • can you please link to what docs/sample code you used to produce your code to programmatically create and register your time based upkeep? Your code is quite different from what's in the docs about programmatic automation registration: https://docs.chain.link/chainlink-automation/register-upkeep/#register-an-upkeep-using-your-own-deployed-contract – ZeusLawyer Dec 26 '22 at 01:28
  • Also, the registrar contract has a registerUpkeep() method (https://goerli.etherscan.io/address/0x02777053d6764996e594c3E88AF1D58D5363a2e6#writeContract) that you dont seem to be calling anywhere etc... – ZeusLawyer Dec 26 '22 at 01:36
  • @ZeusLawyer Thanks, But that link which you shared is for registering custom upkeep right? How would you do the same in the case of a time-based upkeep? – Aashar Dec 26 '22 at 02:21
  • And also I did not use any documentation for my code. I manually created a time-based upkeep on the chainlink website and used it's transaction info to create the same flow of execution with solidity. I am not sure if that was correct as well – Aashar Dec 26 '22 at 02:23
  • Im a bit confused by your question then. Did you follow the process for time-based upkeeps as per the docs? What are your deviations and why? and what is happening with the TX -- you can analyse that using etherscan etc. Please provide information that will help trace your exact steps and where the problem arises, and what the nature of the error is. – ZeusLawyer Dec 27 '22 at 05:53
  • @ZeusLawyer. Thanks for following up. But I was able to figure it out. Instead of using time-based upkeeps, I used custom upkeeps by following their docs and used block.timestamp in the checkUpkeep function to make it execute at certain intervals. – Aashar Dec 28 '22 at 06:27

1 Answers1

0

Contracts cannot execute themselves. Function needs to be called. While contract (function) is not called, contract is sleeping, because every time it makes operations, they should be payed (aka gas), so there is no way to throw an allways-active-timer inside of the contract (infinite gas). It means that you have to make calls manually or use automation services like ChainLink, Openzepplin Defender etc.

You can make a requirement by time-passed with

uint256 private lastTimeStamp;
uint256 private interval;

constructor() {
    lastTimeStamp = block.timestamp;
    interval = 7 days;
}

function isTimePassed() public view returns (bool timePassed) {
    timePassed = ((block.timestamp - lastTimeStamp) > /*7 days */ interval);
    return timePassed;
}

function smth() public {
    (bool timePassed) = isTimePassed();
    ...
}

Something like this.