Skip to content

Commit 18133fd

Browse files
committed
add getAPYs
1 parent 382a182 commit 18133fd

File tree

3 files changed

+63
-1
lines changed

3 files changed

+63
-1
lines changed

bsc/hub_reader/src/HubReader.sol

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ contract HubReader {
2424
stakeHub = IStakeHub(0x0000000000000000000000000000000000002002);
2525
}
2626

27+
/*
28+
* @dev Get validators by offset and limit (pagination)
29+
* @param offset The offset to query validators
30+
* @param limit The limit to query validators
31+
*
32+
* @return The validators
33+
*/
2734
function getValidators(
2835
uint16 offset,
2936
uint16 limit
@@ -54,6 +61,14 @@ contract HubReader {
5461
return validators;
5562
}
5663

64+
/*
65+
* @dev Get current delegations of a delegator
66+
* @param delegator The address of the delegator
67+
* @param offset The offset to query validators
68+
* @param limit The limit to query validators
69+
*
70+
* @return The delegations of the delegator
71+
*/
5772
function getDelegations(
5873
address delegator,
5974
uint16 offset,
@@ -88,4 +103,35 @@ contract HubReader {
88103
}
89104
return delegations;
90105
}
106+
107+
/*
108+
* @dev Get APYs of an array of validators at a given timestamp
109+
* @param operatorAddr The address of the validator
110+
* @param timestamp The timestamp of the block
111+
*
112+
* @return The APYs of the validator in basis points, e.g. 195 is 1.95%
113+
*/
114+
function getAPYs(
115+
address[] memory operatorAddrs,
116+
uint256 timestamp
117+
) external view returns (uint64[] memory) {
118+
uint256 dayIndex = timestamp / stakeHub.BREATHE_BLOCK_INTERVAL();
119+
uint256 length = operatorAddrs.length;
120+
uint64[] memory apys = new uint64[](length);
121+
for (uint256 i = 0; i < length; i++) {
122+
uint256 total = stakeHub.getValidatorTotalPooledBNBRecord(
123+
operatorAddrs[i],
124+
dayIndex
125+
);
126+
uint256 reward = stakeHub.getValidatorRewardRecord(
127+
operatorAddrs[i],
128+
dayIndex
129+
);
130+
if (total == 0 || reward == 0) {
131+
continue;
132+
}
133+
apys[i] = uint64((reward * 365 * 10000) / total);
134+
}
135+
return apys;
136+
}
91137
}

bsc/hub_reader/src/interface/IStakeHub.sol

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ struct Commission {
1515
}
1616

1717
interface IStakeHub {
18+
function BREATHE_BLOCK_INTERVAL() external view returns (uint256);
19+
1820
function getValidators(
1921
uint256 offset,
2022
uint256 limit

bsc/hub_reader/test/HubReader.t.sol

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ contract ValidatorsTest is Test {
1212
}
1313

1414
function test_getValidators() public view {
15-
uint16 limit = 30;
15+
uint16 limit = 10;
1616
Validator[] memory validators = reader.getValidators(0, limit);
1717
assertTrue(validators.length <= limit);
1818

@@ -43,4 +43,18 @@ contract ValidatorsTest is Test {
4343
);
4444
assertTrue(delegations[0].amount > 0);
4545
}
46+
47+
function test_getAPY() public view {
48+
uint256 timestamp = 1715477981;
49+
address[] memory operatorAddrs = new address[](3);
50+
operatorAddrs[0] = address(0x343dA7Ff0446247ca47AA41e2A25c5Bbb230ED0A);
51+
operatorAddrs[1] = address(0xF2B1d86DC7459887B1f7Ce8d840db1D87613Ce7f);
52+
operatorAddrs[2] = address(0x773760b0708a5Cc369c346993a0c225D8e4043B1);
53+
54+
uint64[] memory apys = reader.getAPYs(operatorAddrs, timestamp);
55+
56+
assertEq(apys[0], 193);
57+
assertEq(apys[1], 331);
58+
assertEq(apys[2], 287);
59+
}
4660
}

0 commit comments

Comments
 (0)