Skip to content

Commit

Permalink
build: keeper
Browse files Browse the repository at this point in the history
  • Loading branch information
Schlagonia committed Feb 21, 2024
1 parent 9010180 commit dcaf70c
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 6 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
node-version: 18
- name: Install node.js dependencies
run: yarn --frozen-lockfile
- name: Run linter on *.sol and *.json
Expand Down
60 changes: 60 additions & 0 deletions contracts/Keeper.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// SPDX-License-Identifier: AGPL-3.0
pragma solidity 0.8.18;

interface IStrategy {
function report() external returns (uint256, uint256);

function tend() external;
}

interface IVault {
function process_report(address) external returns (uint256, uint256);
}

/**
* @title Keeper
* @notice
* To allow permissionless reporting on V3 vaults and strategies.
*
* This will do low level calls so that in can be used without reverting
* it the roles have not been set or the functions are not available.
*/
contract Keeper {
/**
* @notice Reports on a strategy.
*/
function report(address _strategy) external returns (uint256, uint256) {
// Call the target with the provided calldata.
(bool success, bytes memory result) = _strategy.call(
abi.encodeWithSelector(IStrategy.report.selector)
);

if (success) {
return abi.decode(result, (uint256, uint256));
}
}

/**
* @notice Tends a strategy.
*/
function tend(address _strategy) external {
_strategy.call(abi.encodeWithSelector(IStrategy.tend.selector));
}

/**
* @notice Report strategy profits on a vault.
*/
function process_report(
address _vault,
address _strategy
) external returns (uint256, uint256) {
// Call the target with the provided calldata.
(bool success, bytes memory result) = _vault.call(
abi.encodeCall(IVault.process_report, _strategy)
);

if (success) {
return abi.decode(result, (uint256, uint256));
}
}
}
10 changes: 5 additions & 5 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,6 @@ def fee_recipient(accounts):
return accounts[4]


@pytest.fixture(scope="session")
def keeper(accounts):
yield accounts[5]


@pytest.fixture(scope="session")
def user(accounts):
return accounts[6]
Expand Down Expand Up @@ -460,3 +455,8 @@ def role_manager(
)

return role_manager


@pytest.fixture(scope="session")
def keeper(daddy):
yield daddy.deploy(project.Keeper)
51 changes: 51 additions & 0 deletions tests/test_keeper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import ape
from ape import chain
from utils.constants import ZERO_ADDRESS, ROLES, MAX_INT


def test_keeper(daddy, keeper, vault, mock_tokenized, amount, user, asset, management):
strategy = mock_tokenized
# Revert on vault does not cause revert
with ape.reverts("not allowed"):
vault.process_report(strategy, sender=keeper)

tx = keeper.process_report(vault, strategy, sender=user)

profit, loss = tx.return_value
assert profit == 0
assert loss == 0

vault.add_strategy(strategy, sender=daddy)
vault.set_role(keeper, ROLES.REPORTING_MANAGER, sender=daddy)

amount = amount // 2

asset.approve(strategy, amount, sender=user)
strategy.deposit(amount, vault, sender=user)

tx = keeper.process_report(vault, strategy, sender=user)

profit, loss = tx.return_value
assert profit == amount
assert loss == 0

asset.transfer(strategy, amount, sender=user)

strategy.setKeeper(user, sender=management)

with ape.reverts("!keeper"):
strategy.report(sender=keeper)

tx = keeper.report(strategy, sender=user)

profit, loss = tx.return_value
assert profit == 0
assert loss == 0

strategy.setKeeper(keeper, sender=management)

tx = keeper.report(strategy, sender=user)

profit, loss = tx.return_value
assert profit == amount
assert loss == 0

0 comments on commit dcaf70c

Please sign in to comment.