Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
2d4952e
wip: RepFI contracts
bengyles Jul 24, 2024
e58726b
Merge branch 'master' into repfi
bengyles Jul 24, 2024
973ac28
fix build
bengyles Jul 26, 2024
378b926
Merge branch 'master' into repfi
bengyles Jul 26, 2024
6e6426e
wip: RepFI contracts
bengyles Jul 26, 2024
381d581
initial draft for token distribution and vesting
bengyles Jul 31, 2024
460cab1
Merge branch 'master' into repfi
bengyles Jul 31, 2024
34e4fb1
Add repfi to deploy script
bengyles Aug 1, 2024
52839dc
fix deployment and add first test
bengyles Aug 2, 2024
8e303e4
Add some tests
bengyles Aug 7, 2024
7698a03
test initialDistribution and TokenVesting
bengyles Aug 12, 2024
4d74db0
reputationMining tests and random number generator
bengyles Aug 16, 2024
cd4b85b
Improve reputation mining and tests
bengyles Aug 19, 2024
280afeb
change totalGlobalReputation to totalPeerValue
bengyles Aug 20, 2024
c891862
remove dependencies and add more tests for initialDistribution
bengyles Aug 20, 2024
1946f12
send leftover repfi to circular contract
bengyles Aug 25, 2024
32833d3
improve comments
bengyles Aug 25, 2024
7a24927
add natspec for repfi contracts and minor improvements
bengyles Aug 27, 2024
92f800a
Peer Staking wip
bengyles Sep 9, 2024
4b4dabe
Peer Staking wip
bengyles Sep 13, 2024
4a1e0f0
add PeerValue contract
bengyles Sep 23, 2024
8d74baa
Merge branch 'master' into repfi
bengyles Sep 23, 2024
6fa689f
Peer staking wip
bengyles Sep 28, 2024
2d3f1d9
introduce negative growth and improve gli by comparing to first period
bengyles Sep 28, 2024
9f9a568
improve PeerStaking contracts
bengyles Oct 4, 2024
fe51a64
Merge branch 'master' into repfi
bengyles Oct 4, 2024
0d3ecf1
fix stack too deep error
bengyles Oct 4, 2024
f64aaae
add peerValue and peerStaking to deploy and test scripts
bengyles Oct 14, 2024
23ddc40
fix tests
bengyles Oct 15, 2024
da68bcf
use separate contracts for vesting and add method to add multiple rec…
bengyles Oct 16, 2024
377e55b
rename repFiRegistry to utilsRegistry
bengyles Oct 16, 2024
6ecc192
Add IREPFI
bengyles Oct 17, 2024
da312d7
change InitialDistribution to Distributor
bengyles Oct 17, 2024
741f793
rename repfi token
bengyles Oct 17, 2024
a62086b
change allocations
bengyles Oct 17, 2024
74628ee
rename pREPFI to cREPFI
bengyles Oct 22, 2024
7583182
improve tests
bengyles Oct 22, 2024
843afcd
remove old todos
bengyles Nov 8, 2024
967325b
rename to cRepFi
bengyles Nov 13, 2024
9481090
fix medium-2
bengyles Nov 13, 2024
3c21e93
fix Low-2
bengyles Nov 13, 2024
f23c115
fix Low-3
bengyles Nov 13, 2024
e99109a
fix Info-1
bengyles Nov 13, 2024
7522f5e
fix Info-3
bengyles Nov 13, 2024
b5e7462
fix Info-2-1
bengyles Nov 13, 2024
be8f2f7
fix Info-2-3
bengyles Nov 13, 2024
db10247
fix best practices
bengyles Nov 13, 2024
987df09
fix best practices
bengyles Nov 13, 2024
65f72a6
Merge branch 'master' into repfi
bengyles Nov 14, 2024
255ea41
Automatically handle period changes in ReputationMining
bengyles Nov 15, 2024
77a9de3
remove comment, MAX_MINT_PER_PERIOD is verified
bengyles Nov 17, 2024
378e6eb
fixed a couple of informational remarks
bengyles Nov 17, 2024
75a797b
check total allocation before vesting
bengyles Nov 17, 2024
3a00773
remove ReentrencyGuard
bengyles Nov 17, 2024
c1a3848
remove reentrancyGuard from ReputationMining
bengyles Nov 17, 2024
23c42d5
fix solidity version
bengyles Nov 17, 2024
9ced5af
use PeerValue contract instead of randomGenerator
bengyles Nov 17, 2024
ce8015b
remove remaining todos, add external wallet addresses to env file and…
bengyles Nov 18, 2024
a315692
rename RepFi to Aut
bengyles Nov 18, 2024
2f99c09
improve comments
bengyles Nov 18, 2024
a83b9da
add restriction to only allow users with an AutID to participate in r…
bengyles Nov 18, 2024
5385d7f
fix renames
bengyles Nov 18, 2024
181e5f8
add a dash to cAut name
bengyles Nov 18, 2024
5361eea
change UtilityToken to ConditionalToken
bengyles Nov 18, 2024
2ba27e0
change UtilityToken to ConditionalToken
bengyles Nov 18, 2024
ade9128
change conditional token to c-token
bengyles Nov 18, 2024
d497676
add readme for ReputationMining
bengyles Nov 19, 2024
3e83f7f
subtract amount from tokensLeft when claiming cAUT
bengyles Nov 24, 2024
0b3ce05
fix medium-3
bengyles Nov 25, 2024
45bd4e0
update distribution values
bengyles Nov 25, 2024
c6ba657
add vesting wallet for advisors and did some renamings to match the docs
bengyles Nov 26, 2024
b76f685
distribute to safe before sending to vesting contract
bengyles Nov 28, 2024
b1c67fa
use reputationMining safe for initial fund distribution
bengyles Dec 3, 2024
0fba3be
use ERC1155 instead of ERC20 for c-aut, transfer c-aut to reputationM…
bengyles Dec 11, 2024
9e1e253
add initial batch functionality
bengyles Dec 11, 2024
fcd32ce
prepare token deployment
bengyles Jan 8, 2025
62ddeaa
Merge branch 'master' into repfi
bengyles Jan 9, 2025
45bca19
add Blaize Security audit report
bengyles Jan 20, 2025
b7d0e96
initial staking contract
bengyles Feb 2, 2025
22cf15b
fix versions
bengyles Feb 4, 2025
7577687
remove vesting
bengyles Feb 4, 2025
712eb15
Staking improvements and tests (wip)
bengyles Feb 18, 2025
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
node_modules
coverage
coverage.json
lcov.info
typechain
tempNet
cache_forge
broadcast
test/testData/LRfuzzDataOut.csv
*.csv
.vscode

# Volumes
volumes/ipfs
Expand Down
Binary file not shown.
2 changes: 1 addition & 1 deletion contracts/autid/AutID.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
pragma solidity 0.8.20;

import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import {IAutID} from "./IAutID.sol";
Expand Down
16 changes: 16 additions & 0 deletions contracts/randomNumberGenerator/IRandomNumberGenerator.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IRandomNumberGenerator {
function getRandomNumberForAccount(address account, uint256 min, uint256 max) external view returns (uint256);

function getRandomPeerValueParametersForAccount(
address account,
uint256 minPS,
uint256 maxPS,
uint256 minP,
uint256 maxP,
uint256 minARing,
uint256 maxARing
) external view returns (uint256 participationScore, uint256 prestige, uint256 a_ring);
}
38 changes: 38 additions & 0 deletions contracts/randomNumberGenerator/RandomNumberGenerator.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

import "./IRandomNumberGenerator.sol";

contract RandomNumberGenerator is IRandomNumberGenerator {
function getRandomNumberForAccount(address account, uint256 min, uint256 max) external view returns (uint256) {
uint randomnumber = uint(keccak256(abi.encodePacked(block.timestamp, account))) % (max - min); // choices in this range
randomnumber += min; // add min to get our start of the range
return randomnumber;
}

function getRandomPeerValueParametersForAccount(
address account,
uint256 minPS,
uint256 maxPS,
uint256 minP,
uint256 maxP,
uint256 minARing,
uint256 maxARing
) external view returns (uint256 participationScore, uint256 prestige, uint256 a_ring) {
uint nonce = 1;
participationScore = uint(keccak256(abi.encodePacked(block.timestamp, account, nonce))) % (maxPS - minPS); // choices in this range
participationScore += minPS; // add min to get our start of the range

nonce++;

prestige = uint(keccak256(abi.encodePacked(block.timestamp, account, nonce))) % (maxP - minP);
prestige += minP;

nonce++;

a_ring = uint(keccak256(abi.encodePacked(block.timestamp, account, nonce))) % (maxARing - minARing);
a_ring += minARing;

return (participationScore, prestige, a_ring);
}
}
32 changes: 32 additions & 0 deletions contracts/repfi/peerStaking/IPeerStaking.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IPeerStaking {
struct Stake {
address staker;
address stakee;
uint256 amount;
uint256 timestamp;
int256 estimatedGrowth;
uint256 duration;
bool active;
}

function initialize(
address initialOwner,
address _autToken,
address _cAutToken,
address _circular,
address _randomNumberGenerator,
address _reputationMining
) external;

function stake(
uint256 amount,
address stakee,
uint256 duration,
int256 expectedGrowth
) external returns (uint256 stakeId);

function unstake(uint256 stakeId) external;
}
164 changes: 164 additions & 0 deletions contracts/repfi/peerStaking/PeerStaking.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {ICAUT} from "../token/IcAUT.sol";
import {IReputationMining} from "../reputationMining/IReputationMining.sol";
import {IRandomNumberGenerator} from "../../randomNumberGenerator/IRandomNumberGenerator.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {IPeerStaking} from "./IPeerStaking.sol";
import {IPeerValue} from "../PeerValue/IPeerValue.sol";

contract PeerStaking is ReentrancyGuard, OwnableUpgradeable, IPeerStaking {
uint256 constant DENOMINATOR = 1000;
/// @notice the Aut token contract
IERC20 public autToken;
/// @notice the c-aut token contract
ICAUT public cAutToken;
/// @notice address where unclaimed funds will be sent to so they can be used by the platform
address public circular;
/// @notice random generator contract where we can get a random value for "peer value" as well was the "total value"
/// @dev this contract will be replaced with the PeerValue contract in the near future, this is just for testing the functionality in the meantime
IPeerValue peerValue;

IReputationMining public reputationMining;

uint256 public totalStakes;

mapping(uint256 stakeId => Stake stake) private stakes;

event StakeAdded(uint256 indexed stakeId, address indexed staker, address indexed stakee, Stake stake);

event StakeClaimed(
uint256 indexed stakeId,
address indexed staker,
address indexed stakee,
Stake stake,
uint256 rewardAmount
);

using SafeERC20 for IERC20;
using SafeERC20 for ICAUT;

/// @notice gap used as best practice for upgradeable contracts
uint256[50] private __gap;

/// @notice PeerStaking contract initializer
/// @param initialOwner The initial owner of the contract
/// @param _autToken the address of the Aut token contract
/// @param _cAutToken the address of the c-aut token contract
/// @param _circular the address of the circular contract
/// @param _peerValue the address of the PeerValue contract
/// @param _reputationMining the address of the reputation mining contract
function initialize(
address initialOwner,
address _autToken,
address _cAutToken,
address _circular,
address _peerValue,
address _reputationMining
) external initializer {
__Ownable_init(initialOwner);
autToken = IERC20(_autToken);
cAutToken = ICAUT(_cAutToken);
circular = _circular;
peerValue = IPeerValue(_peerValue);
reputationMining = IReputationMining(_reputationMining);
}

/// @notice Enables users to stake their tokens and gamble on the future growth of an āut user.
/// @param amount the amount of tokens to stake
/// @param stakee the address of the user that we're tracking the growth of
/// @param duration duration of the stake, in amount of periods
/// @param estimatedGrowth the estimated growth percentage denomincated to 1000 => 100%
function stake(
uint256 amount,
address stakee,
uint256 duration,
int256 estimatedGrowth
) external returns (uint256 stakeId) {
require(amount > 0, "amount must be bigger than 0");
require(stakee != address(0), "invalid staker");
require(duration > 0, "duration is not long enough");
require(estimatedGrowth > 0, "expected growth is too low"); // should be used with denominator, so 20% => 200

// Stakes are possible only on stakees whose ĀutID is 5 periods or older
uint256 age = peerValue.getAge(stakee);
require(age >= 5, "stakee has been active for less than 5 periods");
// limit period (D) of future growth prediction to be lower than or equal to the Age (A) of stakee’s ĀutID.
require(age >= duration, "duration is longer than the stakee's age");

// get current period
uint256 currentPeriod = reputationMining.currentPeriod();
// limit the stake to be equal to or lower than the monthly reward of the staker
uint256 montlyRewardForStaker = reputationMining.getClaimableCTokenForPeriod(msg.sender, currentPeriod);
require(montlyRewardForStaker >= amount, "amount is higher than montly staker reward");

// save the stake in storage
Stake memory newStake = Stake(msg.sender, stakee, amount, currentPeriod, estimatedGrowth, duration, true);
stakeId = totalStakes;

stakes[stakeId] = newStake;

totalStakes++;

emit StakeAdded(stakeId, msg.sender, stakee, newStake);
autToken.safeTransferFrom(msg.sender, address(this), amount);
}

/// @notice Enables users to unstake the stake they have placed earlier. Funds are only claimable once the duration is past
/// @param stakeId The stake ID which was returned after staking
function unstake(uint256 stakeId) external {
// get current period
uint256 currentPeriod = reputationMining.currentPeriod();
// check if the stake exists
Stake storage currentStake = stakes[stakeId];
require(currentStake.amount > 0, "Stake not found");
require(currentStake.active, "stake is not active");
require(currentStake.staker == msg.sender, "msg.sender is not the owner of the stake");
// make sure the duration has passed
require(currentStake.timestamp + currentStake.duration >= currentPeriod, "stake is still ongoing");
// check the stakee's global reputation and compare with the bet that was placed and reward or slash the staking reward depending on the outcome, using a random number for now
uint256 earnedAmount = 0;

uint256 startPeerValue = peerValue.getPeerValue(currentStake.stakee, currentStake.timestamp);
require(startPeerValue > 0, "start peer value does not exist for user");
uint256 actualPeerValue = peerValue.getPeerValue(currentStake.stakee, currentPeriod);
require(actualPeerValue > 0, "Actual peer value does not exist for user");
int256 actualGrowth = int256(((actualPeerValue - startPeerValue) * 100) / startPeerValue);

uint256 age = peerValue.getAge(currentStake.stakee);
(uint256 highestContinuousSegment, uint256 gLi) = peerValue.getGrowthLikelyhood(
currentStake.stakee,
currentStake.estimatedGrowth,
currentStake.duration
);

if (currentStake.estimatedGrowth >= actualGrowth) {
// staker's prediction was correct, thus will be rewarded
if (highestContinuousSegment == 0) {
earnedAmount = (currentStake.amount * 1500) / DENOMINATOR;
} else {
earnedAmount =
(currentStake.amount * (DENOMINATOR + gLi + ((currentStake.duration * DENOMINATOR) / age))) /
DENOMINATOR;
}
} else {
// staker's prediction was wrong thus the staked amount will be slashed
if (highestContinuousSegment == 0) {
earnedAmount = (currentStake.amount * 750) / DENOMINATOR;
} else {
earnedAmount =
(currentStake.amount * (DENOMINATOR - gLi + ((currentStake.duration * DENOMINATOR) / age))) /
DENOMINATOR;
}
}

// set active to false
currentStake.active = false;
emit StakeClaimed(stakeId, msg.sender, currentStake.stakee, currentStake, earnedAmount);
autToken.safeTransfer(msg.sender, earnedAmount);
}
}
24 changes: 24 additions & 0 deletions contracts/repfi/peerValue/IPeerValue.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IPeerValue {
struct PeerValueParams {
uint256 participationScore;
uint256 prestige;
uint256 a_ring;
}

function getPeerValueParams(address account, uint256 period) external returns (PeerValueParams memory);

function getPeerValue(address account, uint256 period) external returns (uint256);

function getTotalPeerValue(uint256 period) external view returns (uint256);

function getAge(address account) external view returns (uint256);

function getGrowthLikelyhood(
address account,
int256 estimatedGrowth,
uint256 duration
) external view returns (uint256 highestContinuousSegment, uint256 gLi);
}
Loading