Skip to content

Commit

Permalink
debugging gone wild
Browse files Browse the repository at this point in the history
  • Loading branch information
MattPereira committed Oct 24, 2023
1 parent 6050df6 commit babecfd
Show file tree
Hide file tree
Showing 24 changed files with 1,048 additions and 406 deletions.
86 changes: 0 additions & 86 deletions CONTRIBUTING.md

This file was deleted.

16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Scaffold Chainlink

A beginner's guide to implimenting chainlink products in your smart contracts. Learn about how to get price feeds on chain, how to get a varifiably random number (VRF) on chain, and how to set up chainlink automation so that keeper nodes trigger your contract.

## Getting Started

1. Install dependencies
Expand All @@ -8,7 +10,9 @@
yarn install
```

2. Deploy the contracts on sepolia network. You will need funds in the deployer account. Visit the [sepolia faucet](https://sepoliafaucet.com/) and set up your .env file in the `packages/hardhat/` folder OR use `yarn generate` and send sepolia ETH to the generated address.
2. Deploy the contracts on sepolia network. Before deployment, you must ensure your deployer account has sepolia ETH and LINK to spend.
a. Grab funds from the [sepolia ETH faucet](https://sepoliafaucet.com/)
b. Grab funds from the [sepolia LINK faucet](https://faucets.chain.link/)

```
yarn deploy --network sepolia
Expand All @@ -20,12 +24,8 @@ yarn deploy --network sepolia
yarn start
```

4. Fund the VRFConsumer contract with LINK. Visit the [LINK faucet](https://faucets.chain.link/)

### Example BG Project Exploration links

- https://jadenkore.medium.com/creating-a-dynamic-nft-that-updates-in-real-time-based-on-chain-data-3d989c04f137
## Price Feeds

- https://app.buidlguidl.com/build/NxKk0AQM5LBm2ks4aSZr
## VRF (Verifiable Random Function)

- https://github.com/danielkhoo/scaffold-eth/tree/buidl-guidl-dynamic-nft
## Automation
104 changes: 75 additions & 29 deletions packages/hardhat/contracts/AutomationConsumer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,57 +2,85 @@
pragma solidity ^0.8.7;

import "@chainlink/contracts/src/v0.8/automation/AutomationCompatible.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { LinkTokenInterface } from "@chainlink/contracts/src/v0.8/shared/interfaces/LinkTokenInterface.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

error AutomationConsumer__UpkeepNotNeeded();

struct RegistrationParams {
string name;
bytes encryptedEmail;
address upkeepContract;
uint32 gasLimit;
address adminAddress;
uint8 triggerType;
bytes checkData;
bytes triggerConfig;
bytes offchainConfig;
uint96 amount;
}

interface AutomationRegistrarInterface {
function registerUpkeep(
RegistrationParams calldata requestParams
) external returns (uint256);
}

/**
* Simple counter contract using chainlink automation
* - try to figure out how to use performData
*
* the upkeep registration process is integrated within this contract
*
*/
contract AutomationConsumer is AutomationCompatibleInterface, Ownable {
event UpkeepPerformed(uint256 indexed timestamp, uint256 indexed counter);
event CounterStarted(uint256 indexed counter);
event CounterStopped(uint256 indexed counter);
event IntervalUpdated(uint256 indexed interval);

uint public counter = 0;
uint public interval = 1 minutes;
uint public maxCounterValue = 10;
bool public isCounting = false;
uint public lastTimeStamp;
IERC20 internal immutable i_linkToken;
uint public s_counter = 0;
uint public s_interval = 30 seconds;
uint public s_maxCounterValue = 10;
bool public s_isCounting = false;
uint public s_lastTimestamp;
uint public s_upkeepID;
LinkTokenInterface public immutable i_link;
AutomationRegistrarInterface public immutable i_registrar;

constructor(address linkTokenAddress) {
i_linkToken = IERC20(linkTokenAddress);
lastTimeStamp = block.timestamp;
constructor(
LinkTokenInterface link,
AutomationRegistrarInterface registrar
) {
i_link = link;
i_registrar = registrar;
}

function startCounting() public {
isCounting = true;
emit CounterStarted(counter);
s_isCounting = true;
s_lastTimestamp = block.timestamp;
emit CounterStarted(s_counter);
}

function stopCounting() public {
isCounting = false;
emit CounterStopped(counter);
s_isCounting = false;
emit CounterStopped(s_counter);
}

function resetCounter() public {
counter = 0;
s_counter = 0;
}

function updateInterval(uint256 _interval) public {
interval = _interval;
emit IntervalUpdated(interval);
s_interval = _interval;
emit IntervalUpdated(s_interval);
}

/**
* - checkData param is not used in this example, but it can be set when the Upkeep is registered
* @return upkeepNeeded - if true, performUpkeep() will be called
* @return performData - data passed to performUpkeep() (can be dynamically computed within checkUpkeep())
*/

function checkUpkeep(
bytes memory /* checkData */
)
Expand All @@ -61,8 +89,8 @@ contract AutomationConsumer is AutomationCompatibleInterface, Ownable {
override
returns (bool upkeepNeeded, bytes memory performData)
{
bool isPastInterval = (block.timestamp - lastTimeStamp) > interval;
upkeepNeeded = isPastInterval && isCounting;
bool isPastInterval = (block.timestamp - s_lastTimestamp) > s_interval;
upkeepNeeded = isPastInterval && s_isCounting;
uint incrementValue = 1;
performData = abi.encode(incrementValue);
return (upkeepNeeded, performData);
Expand All @@ -72,29 +100,47 @@ contract AutomationConsumer is AutomationCompatibleInterface, Ownable {
*
* @param performData returned value from checkUpkeep
*/

function performUpkeep(bytes calldata performData) external override {
// best practice to revalidate upkeep needed before executing any logic in performUpkeep
(bool upkeepNeeded, ) = checkUpkeep(bytes(""));
if (!upkeepNeeded) {
revert AutomationConsumer__UpkeepNotNeeded();
}
if (counter >= maxCounterValue) {
isCounting = false;
counter = 0;
if (s_counter >= s_maxCounterValue) {
s_isCounting = false;
s_counter = 0;
}

uint incrementValue = abi.decode(performData, (uint));
counter += incrementValue;
lastTimeStamp = block.timestamp;
emit UpkeepPerformed(block.timestamp, counter);
s_counter += incrementValue;
s_lastTimestamp = block.timestamp;
emit UpkeepPerformed(block.timestamp, s_counter);
}

/**
* @param params required params for registering an upkeep
*/

function registerNewUpkeep(RegistrationParams memory params) public {
require(
i_link.balanceOf(address(this)) >= params.amount,
"Not enough LINK tokens in this contract"
);
require(
i_link.approve(address(i_registrar), params.amount),
"Failed to approve registrar contract to spend LINK"
);
uint256 upkeepID = i_registrar.registerUpkeep(params);
require(upkeepID != 0, "Upkeep registration failed");
s_upkeepID = upkeepID;
}

// Utilitiy functions
function getLinkBalance() public view returns (uint256) {
return i_linkToken.balanceOf(address(this));
return i_link.balanceOf(address(this));
}

function withdrawLink() public onlyOwner {
i_linkToken.transfer(msg.sender, i_linkToken.balanceOf(address(this)));
i_link.transfer(msg.sender, i_link.balanceOf(address(this)));
}
}
61 changes: 0 additions & 61 deletions packages/hardhat/contracts/RegisterCustomLogicUpkeep.sol

This file was deleted.

6 changes: 3 additions & 3 deletions packages/hardhat/contracts/VRFConsumer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ import "@chainlink/contracts/src/v0.8/vrf/VRFV2WrapperConsumerBase.sol";
import "@chainlink/contracts/src/v0.8/shared/access/ConfirmedOwner.sol";

/**
* if you send 1 link user can spin more than once
* Spin the wheel to get a random number from chainlink VRF
*/

contract VRFConsumer is VRFV2WrapperConsumerBase, ConfirmedOwner {
// State variables
address public linkAddress;
uint32 callbackGasLimit = 100000; // limit for gas can be used when chainlink node calls fulfillRandomWords()
uint16 requestConfirmations = 2; // blocks before chainlink node responds
uint16 requestConfirmations = 3; // blocks before chainlink node responds (must be greater than a minimum amout set by VRF coordinator contract)
uint32 numValues = 1; // how many random numbers to generate

mapping(uint256 => address) public s_spinners; // requestId => msg.sender
Expand Down Expand Up @@ -40,7 +41,6 @@ contract VRFConsumer is VRFV2WrapperConsumerBase, ConfirmedOwner {
* @return requestId each request has a unique ID
*/
function spinWheel() public returns (uint256 requestId) {
// Will revert if link.balanceOf(address(this)) is insufficient
requestId = requestRandomness(
callbackGasLimit,
requestConfirmations,
Expand Down
Loading

0 comments on commit babecfd

Please sign in to comment.