Skip to content

Commit

Permalink
add test for seeker staking capacity
Browse files Browse the repository at this point in the history
  • Loading branch information
JCSanPedro committed Jan 16, 2024
1 parent 703d080 commit 68ae263
Show file tree
Hide file tree
Showing 9 changed files with 571 additions and 110 deletions.
15 changes: 12 additions & 3 deletions contracts/SeekerPowerOracle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
import "@openzeppelin/contracts/utils/introspection/ERC165.sol";

import "./interfaces/ISeekerPowerOracle.sol";

Expand All @@ -13,7 +14,7 @@ import "./interfaces/ISeekerPowerOracle.sol";
* a Seeker's power level via a restricted owner call. Seeker Power can also
* be set by any account if the correct Oracle signature proof is provided.
*/
contract SeekerPowerOracle is ISeekerPowerOracle, Initializable, Ownable2StepUpgradeable {
contract SeekerPowerOracle is ISeekerPowerOracle, Initializable, Ownable2StepUpgradeable, ERC165 {
/**
* @notice The oracle account. This contract accepts any attestations of
* Seeker power that have been signed by this account.
Expand All @@ -33,14 +34,22 @@ contract SeekerPowerOracle is ISeekerPowerOracle, Initializable, Ownable2StepUpg

event SeekerPowerUpdated(uint256 indexed seekerId, uint256 indexed power);

error UnauthorizedSetSeekerCall();
error NonceCannotBeReused();

function initialize(address _oracle) external initializer {
Ownable2StepUpgradeable.__Ownable2Step_init();

oracle = _oracle;
}

error UnauthorizedSetSeekerCall();
error NonceCannotBeReused();
/**
* @notice Returns true if the contract implements the interface defined by
* `interfaceId` from ERC165.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(ISeekerPowerOracle).interfaceId;
}

/**
* @notice Sets the oracle account.
Expand Down
10 changes: 5 additions & 5 deletions contracts/staking/Directory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -117,16 +117,16 @@ contract Directory is IDirectory, Initializable, Manageable, IERC165 {
revert NoStakeToJoinEpoch();
}

uint256 currentStake = _stakingManager.getCurrentStakerAmount(stakee, stakee);

uint256 seekerStakingCapacity = _stakingManager.calculateCapacityFromSeekerPower(seekerId);

// we take the minimum value between the currentStake and the current
// we take the minimum value between the total stake and the current
// staking capacity
if (currentStake > seekerStakingCapacity) {
currentStake = seekerStakingCapacity;
if (totalStake > seekerStakingCapacity) {
totalStake = seekerStakingCapacity;
}

uint256 currentStake = _stakingManager.getCurrentStakerAmount(stakee, stakee);

uint16 ownedStakeProportion = SyloUtils.asPerc(
SafeCast.toUint128(currentStake),
totalStake
Expand Down
14 changes: 13 additions & 1 deletion contracts/staking/StakingManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ import "../interfaces/ISeekerPowerOracle.sol";
* and delegated stakers are rewarded on a pro-rata basis.
*/
contract StakingManager is IStakingManager, Initializable, Ownable2StepUpgradeable, ERC165 {
// The maximum possible SYLO that exists in the network. Naturally
// represents the maximum possible SYLO that can be staked.
uint256 internal constant MAX_SYLO = 10_000_000_000 ether;

/** ERC 20 compatible token we are dealing with */
IERC20 public _token;

Expand Down Expand Up @@ -327,7 +331,15 @@ contract StakingManager is IStakingManager, Initializable, Ownable2StepUpgradeab
revert SeekerPowerNotRegistered(seekerId);
}

return seekerId ** 2;
// If the Seeker Power is already
// at the maximum sylo, then we just return the max sylo value directly.
if (seekerPower >= MAX_SYLO) {
return MAX_SYLO;
}

uint256 capacity = seekerPower ** 2 * 1 ether;

return capacity > MAX_SYLO ? MAX_SYLO : capacity;
}

/**
Expand Down
57 changes: 51 additions & 6 deletions test/payments/multiReceiverTicketing.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
EpochsManager,
Registries,
RewardsManager,
SeekerPowerOracle,
StakingManager,
SyloTicketing,
SyloToken,
Expand Down Expand Up @@ -34,6 +35,7 @@ describe('MultiReceiverTicketing', () => {
let registries: Registries;
let stakingManager: StakingManager;
let seekers: TestSeekers;
let seekerPowerOracle: SeekerPowerOracle;
let futurepassRegistrar: TestFuturepassRegistrar;

before(async () => {
Expand All @@ -57,6 +59,7 @@ describe('MultiReceiverTicketing', () => {
registries = contracts.registries;
stakingManager = contracts.stakingManager;
seekers = contracts.seekers;
seekerPowerOracle = contracts.seekerPowerOracle;
futurepassRegistrar = contracts.futurepassRegistrar;

await token.approve(await stakingManager.getAddress(), toSOLOs(10000000));
Expand All @@ -65,7 +68,14 @@ describe('MultiReceiverTicketing', () => {

it('can redeem multi receiver ticket', async () => {
await stakingManager.addStake(toSOLOs(1), owner);
await setSeekerRegistry(seekers, registries, accounts[0], accounts[1], 1);
await setSeekerRegistry(
seekers,
registries,
seekerPowerOracle,
accounts[0],
accounts[1],
1,
);

await epochsManager.joinNextEpoch();
await epochsManager.initializeEpoch();
Expand Down Expand Up @@ -115,7 +125,14 @@ describe('MultiReceiverTicketing', () => {
await ticketingParameters.setTicketDuration(10000000000);

await stakingManager.addStake(toSOLOs(1), owner);
await setSeekerRegistry(seekers, registries, accounts[0], accounts[1], 1);
await setSeekerRegistry(
seekers,
registries,
seekerPowerOracle,
accounts[0],
accounts[1],
1,
);

await epochsManager.joinNextEpoch();
await epochsManager.initializeEpoch();
Expand Down Expand Up @@ -295,7 +312,14 @@ describe('MultiReceiverTicketing', () => {
await ticketingParameters.setBaseLiveWinProb(0);

await stakingManager.addStake(toSOLOs(1), owner);
await setSeekerRegistry(seekers, registries, accounts[0], accounts[1], 1);
await setSeekerRegistry(
seekers,
registries,
seekerPowerOracle,
accounts[0],
accounts[1],
1,
);

await epochsManager.joinNextEpoch();
await epochsManager.initializeEpoch();
Expand Down Expand Up @@ -355,7 +379,14 @@ describe('MultiReceiverTicketing', () => {

it('cannot redeem multi receiver ticket if node has not joined epoch', async () => {
await stakingManager.addStake(toSOLOs(1), owner);
await setSeekerRegistry(seekers, registries, accounts[0], accounts[1], 1);
await setSeekerRegistry(
seekers,
registries,
seekerPowerOracle,
accounts[0],
accounts[1],
1,
);

await epochsManager.initializeEpoch();

Expand Down Expand Up @@ -391,7 +422,14 @@ describe('MultiReceiverTicketing', () => {

it('can not redeem for non valid receiver', async () => {
await stakingManager.addStake(toSOLOs(1), owner);
await setSeekerRegistry(seekers, registries, accounts[0], accounts[1], 1);
await setSeekerRegistry(
seekers,
registries,
seekerPowerOracle,
accounts[0],
accounts[1],
1,
);

await epochsManager.joinNextEpoch();
await epochsManager.initializeEpoch();
Expand Down Expand Up @@ -428,7 +466,14 @@ describe('MultiReceiverTicketing', () => {

it('can not redeem for the same user more than once', async () => {
await stakingManager.addStake(toSOLOs(1), owner);
await setSeekerRegistry(seekers, registries, accounts[0], accounts[1], 1);
await setSeekerRegistry(
seekers,
registries,
seekerPowerOracle,
accounts[0],
accounts[1],
1,
);

await epochsManager.joinNextEpoch();
await epochsManager.initializeEpoch();
Expand Down
Loading

0 comments on commit 68ae263

Please sign in to comment.