Skip to content
This repository was archived by the owner on Apr 2, 2026. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 25 additions & 13 deletions contracts/global/LagrangeDistributor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@1inch/solidity-utils/contracts/libraries/SafeERC20.sol";

import {ILPNClient} from "../interfaces/lagrange/ILPNClient.sol";
import {ILPNRegistry} from "../interfaces/lagrange/ILPNRegistry.sol";
import {QueryParams} from "../interfaces/lagrange/QueryParams.sol";
import {ILPNClientV1} from "../interfaces/lagrange/ILPNClientV1.sol";
import {ILPNRegistryV1, QueryOutput} from "../interfaces/lagrange/ILPNRegistryV1.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

struct RewardData {
Expand Down Expand Up @@ -57,10 +56,19 @@ interface ILagrangeDistributorExceptions {
/// @dev Precision for the propotional balance integral
uint256 constant PROPORTIONAL_BALANCE_PRECISION = 10 ** 18;

contract LagrangeDistributor is Ownable, ILPNClient, ILagrangeDistributorExceptions, ILagrangeDistributorEvents {
using QueryParams for QueryParams.ERC20QueryParams;
contract LagrangeDistributor is Ownable, ILPNClientV1, ILagrangeDistributorExceptions, ILagrangeDistributorEvents {
using SafeERC20 for IERC20;

/// @notice Columns expected in the query result
struct ExpectedResultRow {
uint256 integral;
}

// TODO: Register a query and fill this in
/// @notice The query hash corresponding to a proportionate balance query of a particular ERC20 table
bytes32 public constant GEARBOX_PROPORTIONATE_BALANCE_QUERY_HASH =
0x0000000000000000000000000000000000000000000000000000000000000000;

/// @notice Address of the LPN registry
address public immutable lpnRegistry;

Expand Down Expand Up @@ -92,11 +100,14 @@ contract LagrangeDistributor is Ownable, ILPNClient, ILagrangeDistributorExcepti

/// @notice Callback function called by the LPNRegistry contract.
/// @param requestId The ID of the request.
/// @param results The result of the request.
function lpnCallback(uint256 requestId, uint256[] calldata results) external lpnRegistryOnly {
/// @param result The result of the request.
function lpnCallback(uint256 requestId, QueryOutput calldata result) external lpnRegistryOnly {
uint256 campaignId = requestData[requestId].campaignId;
address holder = requestData[requestId].holder;
uint256 integral = results[0];

if (result.rows.length == 0) return;

uint256 integral = abi.decode(result.rows[0], (ExpectedResultRow)).integral;

if (integral == 0) return;

Expand Down Expand Up @@ -130,11 +141,12 @@ contract LagrangeDistributor is Ownable, ILPNClient, ILagrangeDistributorExcepti
endBlock = block.number > endBlock ? endBlock : block.number;
endBlock = endBlock - 1;

uint256 requestId = ILPNRegistry(lpnRegistry).request{value: ILPNRegistry(lpnRegistry).gasFee()}(
queriedToken,
QueryParams.newERC20QueryParams(holder, uint88(PROPORTIONAL_BALANCE_PRECISION)).toBytes32(),
startBlock,
endBlock
bytes32[] memory placeholders = new bytes32[](2);
placeholders[0] = bytes32(bytes20(holder));
placeholders[1] = bytes32(PROPORTIONAL_BALANCE_PRECISION);

uint256 requestId = ILPNRegistryV1(lpnRegistry).request{value: ILPNRegistryV1(lpnRegistry).gasFee()}(
GEARBOX_PROPORTIONATE_BALANCE_QUERY_HASH, placeholders, startBlock, endBlock
);

_campaigns[campaignId].blockLU[holder] = block.number;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {QueryOutput} from "./ILPNRegistryV1.sol";

/**
* @title ILPNClient
* @notice Interface for the LPNClientV0 contract.
*/
interface ILPNClient {
interface ILPNClientV1 {
/// @notice Callback function called by the LPNRegistry contract.
/// @param requestId The ID of the request.
/// @param results The result of the request.
function lpnCallback(uint256 requestId, uint256[] calldata results)
external;
}
/// @param result The result of the request.
function lpnCallback(uint256 requestId, QueryOutput calldata result) external;
}
Original file line number Diff line number Diff line change
@@ -1,61 +1,50 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/// @title ILPNRegistry
/// @notice Interface for the LPNRegistryV0 contract.
interface ILPNRegistry {
/// @notice Event emitted when a new client registers.
/// @param storageContract The address of the smart contract to be indexed.
/// @param client The address of the client who requested this contract to be indexed.
/// @param mappingSlot The storage slot of the client's mapping to be computed and proved over.
/// @param lengthSlot The storage slot of the variable storing the length of the client's mapping.
event NewRegistration(
address indexed storageContract, address indexed client, uint256 mappingSlot, uint256 lengthSlot
);
/// The query output struct returned from the processQuery function
struct QueryOutput {
// Total number of the all matching rows
uint256 totalMatchedRows;
// Returned rows of the current cursor
bytes[] rows;
}

/// @title IQueryManager
/// @notice
interface IQueryManager {
/// @notice Event emitted when a new request is made.
/// @param requestId The ID of the request.
/// @param storageContract The address of the smart contract with the storage associated with the request.
/// @param queryHash The identifier of the SQL query associated with the request.
/// @param client The address of the client who made this request.
/// @param params The query params associated with this query type.
/// @param placeholders Values for the numbered placeholders in the query.
/// @param startBlock The starting block for the computation.
/// @param endBlock The ending block for the computation.
/// @param proofBlock The requested block for the proof to be computed against.
/// Currently required for OP Stack chains
event NewRequest(
uint256 indexed requestId,
address indexed storageContract,
bytes32 indexed queryHash,
address indexed client,
bytes32 params,
bytes32[] placeholders,
uint256 startBlock,
uint256 endBlock,
uint256 offset,
uint256 gasFee,
uint256 proofBlock
);

/// @notice Event emitted when a response is received.
/// @param requestId The ID of the request.
/// @param client The address of the client who made the matching request.
/// @param results The computed results for the request.
event NewResponse(uint256 indexed requestId, address indexed client, uint256[] results);

/// @notice The gas fee paid for on request to reimburse the response transaction.
function gasFee() external returns (uint256);

/// @notice Registers a client with the provided mapping and length slots.
/// @param storageContract The address of the contract to be queried.
/// @param mappingSlot The storage slot of the client's mapping to be computed and proved over.
/// @param lengthSlot The storage slot of the variable storing the length of the client's mapping.
function register(address storageContract, uint256 mappingSlot, uint256 lengthSlot) external;
/// @param result The computed results for the request.
event NewResponse(uint256 indexed requestId, address indexed client, QueryOutput result);

/// @notice Submits a new request to the registry.
/// @param storageContract The address of the smart contract with the storage associated with the request.
/// @param params The query params associated with this query type.
/// @param queryHash The identifier of the SQL query associated with the request.
/// @param placeholders Values for the numbered placeholders in the query.
/// @param startBlock The starting block for the computation.
/// @param endBlock The ending block for the computation.
/// @return The ID of the newly created request.
function request(address storageContract, bytes32 params, uint256 startBlock, uint256 endBlock)
function request(bytes32 queryHash, bytes32[] calldata placeholders, uint256 startBlock, uint256 endBlock)
external
payable
returns (uint256);
Expand All @@ -69,3 +58,25 @@ interface ILPNRegistry {
/// @param blockNumber The block number of the block hash corresponding to the proof.
function respond(uint256 requestId_, bytes32[] calldata data, uint256 blockNumber) external;
}

/// @title IRegistrationManager
/// @notice
interface IRegistrationManager {
event NewTableRegistration(
bytes32 indexed hash,
address indexed contractAddr,
uint256 chainId,
uint256 genesisBlock,
string name,
string schema
);

event NewQueryRegistration(bytes32 indexed hash, bytes32 indexed tableHash, string sql);

function registerQuery(bytes32 hash, bytes32 tableHash, string calldata sql) external;
}

interface ILPNRegistryV1 is IQueryManager, IRegistrationManager {
/// @notice The gas fee paid for on request to reimburse the response transaction.
function gasFee() external returns (uint256);
}