Skip to content

Commit

Permalink
Merge pull request #26 from valory-xyz/requester_activity_checker
Browse files Browse the repository at this point in the history
feat: separating between mech and requester activity checker
  • Loading branch information
DavidMinarsch authored Aug 28, 2024
2 parents 861a592 + 10f0ee1 commit 7a9f2ab
Show file tree
Hide file tree
Showing 14 changed files with 531 additions and 70 deletions.
34 changes: 17 additions & 17 deletions abis/0.8.25/MechActivityChecker.json

Large diffs are not rendered by default.

111 changes: 111 additions & 0 deletions abis/0.8.25/RequesterActivityChecker.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
{
"_format": "hh-sol-artifact-1",
"contractName": "RequesterActivityChecker",
"sourceName": "contracts/mech_usage/RequesterActivityChecker.sol",
"abi": [
{
"inputs": [
{
"internalType": "address",
"name": "_mechMarketplace",
"type": "address"
},
{
"internalType": "uint256",
"name": "_livenessRatio",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "ZeroAddress",
"type": "error"
},
{
"inputs": [],
"name": "ZeroValue",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "multisig",
"type": "address"
}
],
"name": "getMultisigNonces",
"outputs": [
{
"internalType": "uint256[]",
"name": "nonces",
"type": "uint256[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256[]",
"name": "curNonces",
"type": "uint256[]"
},
{
"internalType": "uint256[]",
"name": "lastNonces",
"type": "uint256[]"
},
{
"internalType": "uint256",
"name": "ts",
"type": "uint256"
}
],
"name": "isRatioPass",
"outputs": [
{
"internalType": "bool",
"name": "ratioPass",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "livenessRatio",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "mechMarketplace",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
}
],
"bytecode": "0x60c060405234801561000f575f80fd5b506040516107b43803806107b483398101604081905261002e9161008b565b80805f0361004f57604051637c946ed760e01b815260040160405180910390fd5b6080526001600160a01b0382166100795760405163d92e233d60e01b815260040160405180910390fd5b506001600160a01b031660a0526100c2565b5f806040838503121561009c575f80fd5b82516001600160a01b03811681146100b2575f80fd5b6020939093015192949293505050565b60805160a0516106c56100ef5f395f818160b0015261036501525f8181607b015261024701526106c55ff3fe608060405234801561000f575f80fd5b506004361061004a575f3560e01c8063184023a51461004e578063592cf3fb146100765780639c5e9590146100ab578063d564c4bf146100f7575b5f80fd5b61006161005c3660046104d8565b610117565b60405190151581526020015b60405180910390f35b61009d7f000000000000000000000000000000000000000000000000000000000000000081565b60405190815260200161006d565b6100d27f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161006d565b61010a610105366004610540565b610276565b60405161006d9190610573565b5f80821180156101585750825f81518110610134576101346105b6565b6020026020010151845f8151811061014e5761014e6105b6565b6020026020010151115b8015610197575082600181518110610172576101726105b6565b60200260200101518460018151811061018d5761018d6105b6565b6020026020010151115b1561026f575f835f815181106101af576101af6105b6565b6020026020010151855f815181106101c9576101c96105b6565b60200260200101516101db9190610610565b90505f846001815181106101f1576101f16105b6565b60200260200101518660018151811061020c5761020c6105b6565b602002602001015161021e9190610610565b905081811161026c575f8461023b83670de0b6b3a7640000610629565b6102459190610640565b7f000000000000000000000000000000000000000000000000000000000000000011159350505b50505b9392505050565b60408051600280825260608083018452926020830190803683370190505090508173ffffffffffffffffffffffffffffffffffffffff1663affed0e06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102df573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103039190610678565b815f81518110610315576103156105b6565b60209081029190910101526040517f7af7347300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301527f00000000000000000000000000000000000000000000000000000000000000001690637af7347390602401602060405180830381865afa1580156103aa573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103ce9190610678565b816001815181106103e1576103e16105b6565b602002602001018181525050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f82601f83011261042e575f80fd5b8135602067ffffffffffffffff8083111561044b5761044b6103f2565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f8301168101818110848211171561048e5761048e6103f2565b60405293845260208187018101949081019250878511156104ad575f80fd5b6020870191505b848210156104cd578135835291830191908301906104b4565b979650505050505050565b5f805f606084860312156104ea575f80fd5b833567ffffffffffffffff80821115610501575f80fd5b61050d8783880161041f565b94506020860135915080821115610522575f80fd5b5061052f8682870161041f565b925050604084013590509250925092565b5f60208284031215610550575f80fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461026f575f80fd5b602080825282518282018190525f9190848201906040850190845b818110156105aa5783518352928401929184019160010161058e565b50909695505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b81810381811115610623576106236105e3565b92915050565b8082028115828204841417610623576106236105e3565b5f82610673577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b500490565b5f60208284031215610688575f80fd5b505191905056fea26469706673582212207d2d622fb2a98a97e70a598e42d992d549df8f2ed401f4d4ba67415f8da4b7d364736f6c63430008190033",
"deployedBytecode": "0x608060405234801561000f575f80fd5b506004361061004a575f3560e01c8063184023a51461004e578063592cf3fb146100765780639c5e9590146100ab578063d564c4bf146100f7575b5f80fd5b61006161005c3660046104d8565b610117565b60405190151581526020015b60405180910390f35b61009d7f000000000000000000000000000000000000000000000000000000000000000081565b60405190815260200161006d565b6100d27f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161006d565b61010a610105366004610540565b610276565b60405161006d9190610573565b5f80821180156101585750825f81518110610134576101346105b6565b6020026020010151845f8151811061014e5761014e6105b6565b6020026020010151115b8015610197575082600181518110610172576101726105b6565b60200260200101518460018151811061018d5761018d6105b6565b6020026020010151115b1561026f575f835f815181106101af576101af6105b6565b6020026020010151855f815181106101c9576101c96105b6565b60200260200101516101db9190610610565b90505f846001815181106101f1576101f16105b6565b60200260200101518660018151811061020c5761020c6105b6565b602002602001015161021e9190610610565b905081811161026c575f8461023b83670de0b6b3a7640000610629565b6102459190610640565b7f000000000000000000000000000000000000000000000000000000000000000011159350505b50505b9392505050565b60408051600280825260608083018452926020830190803683370190505090508173ffffffffffffffffffffffffffffffffffffffff1663affed0e06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102df573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103039190610678565b815f81518110610315576103156105b6565b60209081029190910101526040517f7af7347300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301527f00000000000000000000000000000000000000000000000000000000000000001690637af7347390602401602060405180830381865afa1580156103aa573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103ce9190610678565b816001815181106103e1576103e16105b6565b602002602001018181525050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f82601f83011261042e575f80fd5b8135602067ffffffffffffffff8083111561044b5761044b6103f2565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f8301168101818110848211171561048e5761048e6103f2565b60405293845260208187018101949081019250878511156104ad575f80fd5b6020870191505b848210156104cd578135835291830191908301906104b4565b979650505050505050565b5f805f606084860312156104ea575f80fd5b833567ffffffffffffffff80821115610501575f80fd5b61050d8783880161041f565b94506020860135915080821115610522575f80fd5b5061052f8682870161041f565b925050604084013590509250925092565b5f60208284031215610550575f80fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461026f575f80fd5b602080825282518282018190525f9190848201906040850190845b818110156105aa5783518352928401929184019160010161058e565b50909695505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b81810381811115610623576106236105e3565b92915050565b8082028115828204841417610623576106236105e3565b5f82610673577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b500490565b5f60208284031215610688575f80fd5b505191905056fea26469706673582212207d2d622fb2a98a97e70a598e42d992d549df8f2ed401f4d4ba67415f8da4b7d364736f6c63430008190033",
"linkReferences": {},
"deployedLinkReferences": {}
}
40 changes: 20 additions & 20 deletions contracts/mech_usage/MechActivityChecker.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,42 +10,42 @@ interface IMultisig {
function nonce() external view returns (uint256);
}

// AgentMech interface
interface IAgentMech {
/// @dev Gets the requests count for a specific account.
/// @param account Account address.
/// @return requestsCount Requests count.
function getRequestsCount(address account) external view returns (uint256 requestsCount);
// Mech Marketplace interface
interface IMechMarketplace {
/// @dev Gets deliveries count for a specific mech service multisig.
/// @param mechService Agent mech service multisig address.
/// @return Deliveries count.
function getMechServiceDeliveriesCount(address mechService) external view returns (uint256);
}

/// @dev Provided zero mech agent address.
error ZeroMechAgentAddress();
/// @dev Provided zero address.
error ZeroAddress();

/// @title MechAgentMod - Smart contract for AI agent mech staking modification
/// @title MechActivityChecker - Smart contract for mech staking activity checking
/// @author Aleksandr Kuperman - <[email protected]>
/// @author Andrey Lebedev - <[email protected]>
/// @author Mariapia Moscatiello - <[email protected]>
contract MechActivityChecker is StakingActivityChecker{
// AI agent mech contract address.
address public immutable agentMech;
// AI agent mech marketplace contract address.
address public immutable mechMarketplace;

/// @dev MechAgentMod constructor.
/// @param _agentMech AI agent mech contract address.
/// @dev MechActivityChecker constructor.
/// @param _mechMarketplace AI agent mech marketplace contract address.
/// @param _livenessRatio Liveness ratio in the format of 1e18.
constructor(address _agentMech, uint256 _livenessRatio) StakingActivityChecker(_livenessRatio) {
if (_agentMech == address(0)) {
revert ZeroMechAgentAddress();
constructor(address _mechMarketplace, uint256 _livenessRatio) StakingActivityChecker(_livenessRatio) {
if (_mechMarketplace == address(0)) {
revert ZeroAddress();
}
agentMech = _agentMech;
mechMarketplace = _mechMarketplace;
}

/// @dev Gets service multisig nonces.
/// @param multisig Service multisig address.
/// @return nonces Set of a nonce and a requests count for the multisig.
/// @return nonces Set of a nonce and a deliveries count for the multisig.
function getMultisigNonces(address multisig) external view virtual override returns (uint256[] memory nonces) {
nonces = new uint256[](2);
nonces[0] = IMultisig(multisig).nonce();
nonces[1] = IAgentMech(agentMech).getRequestsCount(multisig);
nonces[1] = IMechMarketplace(mechMarketplace).getMechServiceDeliveriesCount(multisig);
}

/// @dev Checks if the service multisig liveness ratio passes the defined liveness threshold.
Expand Down
82 changes: 82 additions & 0 deletions contracts/mech_usage/RequesterActivityChecker.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;

import {StakingActivityChecker} from "../../lib/autonolas-registries/contracts/staking/StakingActivityChecker.sol";

// Multisig interface
interface IMultisig {
/// @dev Gets the multisig nonce.
/// @return Multisig nonce.
function nonce() external view returns (uint256);
}

// Mech Marketplace interface
interface IMechMarketplace {
/// @dev Gets the requests count for a specific account.
/// @param account Account address.
/// @return requestsCount Requests count.
function getRequestsCount(address account) external view returns (uint256 requestsCount);
}

/// @dev Provided zero address.
error ZeroAddress();

/// @title RequesterActivityChecker - Smart contract for requester staking activity checking
/// @author Aleksandr Kuperman - <[email protected]>
/// @author Andrey Lebedev - <[email protected]>
/// @author Mariapia Moscatiello - <[email protected]>
contract RequesterActivityChecker is StakingActivityChecker{
// AI agent mech marketplace contract address.
address public immutable mechMarketplace;

/// @dev RequesterActivityChecker constructor.
/// @param _mechMarketplace AI agent mech marketplace contract address.
/// @param _livenessRatio Liveness ratio in the format of 1e18.
constructor(address _mechMarketplace, uint256 _livenessRatio) StakingActivityChecker(_livenessRatio) {
if (_mechMarketplace == address(0)) {
revert ZeroAddress();
}
mechMarketplace = _mechMarketplace;
}

/// @dev Gets service multisig nonces.
/// @param multisig Service multisig address.
/// @return nonces Set of a nonce and a requests count for the multisig.
function getMultisigNonces(address multisig) external view virtual override returns (uint256[] memory nonces) {
nonces = new uint256[](2);
nonces[0] = IMultisig(multisig).nonce();
nonces[1] = IMechMarketplace(mechMarketplace).getRequestsCount(multisig);
}

/// @dev Checks if the service multisig liveness ratio passes the defined liveness threshold.
/// @notice The formula for calculating the ratio is the following:
/// currentNonces - [service multisig nonce at time now (block.timestamp), requests count at time now];
/// lastNonces - [service multisig nonce at the previous checkpoint or staking time (tsStart), requests count at time tsStart];
/// Requests count difference must be smaller or equal to the nonce difference:
/// (currentNonces[1] - lastNonces[1]) <= (currentNonces[0] - lastNonces[0]);
/// ratio = (currentNonces[1] - lastNonce[1]) / (block.timestamp - tsStart),
/// where ratio >= livenessRatio.
/// @param curNonces Current service multisig set of nonce and requests count.
/// @param lastNonces Last service multisig set of nonce and requests count.
/// @param ts Time difference between current and last timestamps.
/// @return ratioPass True, if the liveness ratio passes the check.
function isRatioPass(
uint256[] memory curNonces,
uint256[] memory lastNonces,
uint256 ts
) external view virtual override returns (bool ratioPass)
{
// If the checkpoint was called in the exact same block, the ratio is zero
// If the current nonce is not greater than the last nonce, the ratio is zero
// If the current requests count is not greater than the last requests count, the ratio is zero
if (ts > 0 && curNonces[0] > lastNonces[0] && curNonces[1] > lastNonces[1]) {
uint256 diffNonces = curNonces[0] - lastNonces[0];
uint256 diffRequestsCounts = curNonces[1] - lastNonces[1];
// Requests counts difference must be less or equal to the nonce difference
if (diffRequestsCounts <= diffNonces) {
uint256 ratio = (diffRequestsCounts * 1e18) / ts;
ratioPass = (ratio >= livenessRatio);
}
}
}
}
36 changes: 30 additions & 6 deletions contracts/test/MockAgentMech.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,41 @@ pragma solidity ^0.8.25;
/// @title MockAgentMech - Smart contract for mocking AgentMech partial functionality.
contract MockAgentMech {
event requestsCountIncreased(address indexed account, uint256 requestsCount);
event deliveriesCountIncreased(address indexed account, uint256 deliveriesCount);
event operatorDeliveriesCountIncreased(address indexed operator, uint256 deliveriesCount);

// Map of requests counts for corresponding requester
mapping (address => uint256) public mapRequestCounts;
// Map of requests counts for corresponding requester
mapping (address => uint256) public mapDeliveryCounts;
// Map of requests counts for corresponding operator
mapping (address => uint256) public mapMechServiceDeliveryCounts;

// Map of requests counts for corresponding addresses
mapping (address => uint256) public mapRequestsCounts;

function increaseRequestsCount(address account) external {
mapRequestsCounts[account]++;
emit requestsCountIncreased(account, mapRequestsCounts[account]);
mapRequestCounts[account]++;
emit requestsCountIncreased(account, mapRequestCounts[account]);
}

function increaseDeliveriesCount(address account) external {
mapDeliveryCounts[account]++;
emit deliveriesCountIncreased(account, mapDeliveryCounts[account]);
}

function increaseMechServiceDeliveriesCount(address operator) external {
mapMechServiceDeliveryCounts[operator]++;
emit operatorDeliveriesCountIncreased(operator, mapMechServiceDeliveryCounts[operator]);
}

function getRequestsCount(address account) external view returns (uint256) {
return mapRequestCounts[account];
}

function getRequestsCount(address account) external view returns (uint256 requestsCount) {
requestsCount = mapRequestsCounts[account];
function getDeliveriesCount(address account) external view returns (uint256) {
return mapDeliveryCounts[account];
}

function getMechServiceDeliveriesCount(address account) external view returns (uint256) {
return mapMechServiceDeliveryCounts[account];
}
}
4 changes: 2 additions & 2 deletions scripts/deployment/deploy_01_mech_activity_checker.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ async function main() {
const derivationPath = parsedData.derivationPath;
const providerName = parsedData.providerName;
const gasPriceInGwei = parsedData.gasPriceInGwei;
const agentMechAddress = parsedData.agentMechAddress;
const mechMarketplaceAddress = parsedData.mechMarketplaceAddress;
const livenessRatio = parsedData.livenessRatio;

let networkURL = parsedData.networkURL;
Expand Down Expand Up @@ -47,7 +47,7 @@ async function main() {
const gasPrice = ethers.utils.parseUnits(gasPriceInGwei, "gwei");
const MechActivityChecker = await ethers.getContractFactory("MechActivityChecker");
console.log("You are signing the following transaction: MechActivityChecker.connect(EOA).deploy()");
const mechActivityChecker = await MechActivityChecker.connect(EOA).deploy(agentMechAddress, livenessRatio,
const mechActivityChecker = await MechActivityChecker.connect(EOA).deploy(mechMarketplaceAddress, livenessRatio,
{ gasPrice });
const result = await mechActivityChecker.deployed();

Expand Down
Loading

0 comments on commit 7a9f2ab

Please sign in to comment.