Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
7750bf3
initial security pool draft
KillariDev Oct 6, 2025
9303526
open oracle contracts
KillariDev Oct 6, 2025
bec70b9
Rename Auction.Sol to Auction.sol
KillariDev Oct 6, 2025
e6b84ed
Merge branch 'main' into security-pool-draft
KillariDev Oct 8, 2025
f50465f
first tests, can deploy
KillariDev Oct 8, 2025
7aa871a
fixes
KillariDev Oct 8, 2025
2538fa1
happy path
KillariDev Oct 10, 2025
70e892a
log printing, cleanup
KillariDev Oct 13, 2025
62045b0
some progress
KillariDev Oct 13, 2025
4771f4e
call trace, about to fork, retention rate changes
KillariDev Oct 14, 2025
a167feb
forking
KillariDev Oct 14, 2025
59e4840
forking suff
KillariDev Oct 14, 2025
0192393
create2
KillariDev Oct 15, 2025
15e4dd8
convert solidity output to typescript types refactor
KillariDev Oct 16, 2025
f507a4e
fixes
KillariDev Oct 16, 2025
50d1e76
fork migration fixes
KillariDev Oct 17, 2025
6a2dd53
move weth and iaugur o peripehy
KillariDev Oct 17, 2025
032e94e
remove prints
KillariDev Oct 17, 2025
39ac728
cleanup
KillariDev Oct 17, 2025
eb3e269
update viem, error handling
KillariDev Oct 17, 2025
2c5924b
Merge branch 'main' into security-pool-draft
KillariDev Oct 17, 2025
42af027
refactor, attack forking
KillariDev Oct 20, 2025
4da36b4
refactoring & fixing
KillariDev Oct 20, 2025
f20b02f
security pool utils
KillariDev Oct 20, 2025
eed4dc0
auction working, refactor, transaction explainer now explains outputs
KillariDev Oct 21, 2025
82016a5
add some error logging and enable caching
KillariDev Oct 21, 2025
c441c35
remove comments
KillariDev Oct 21, 2025
1822236
rename
KillariDev Oct 21, 2025
1bcc340
rename
KillariDev Oct 21, 2025
b2f9e51
Merge branch 'main' into security-pool-draft
KillariDev Oct 21, 2025
3fba083
use ErrorWithDataAndCode
KillariDev Oct 21, 2025
c558998
typo
KillariDev Oct 21, 2025
1e7e0b1
Merge branch 'main' into security-pool-draft
KillariDev Oct 22, 2025
5fc54e8
move iweth9 and iaugur to interfaces
KillariDev Oct 22, 2025
6e4c6ce
rename repShares -> poolOwnership
KillariDev Oct 22, 2025
dbbc53b
rename `0x${ string }` -> EthereumAddressString
KillariDev Oct 22, 2025
00557e4
make things immutable
KillariDev Oct 22, 2025
452a032
Merge pull request #13 from AugurProject/move-to-interfaces
KillariDev Oct 23, 2025
82fff84
Merge pull request #14 from AugurProject/rename-repShares
KillariDev Oct 23, 2025
27d63b2
revert oxstring stuff
KillariDev Oct 23, 2025
d6cce99
cleanup
KillariDev Oct 23, 2025
f722b71
Merge pull request #16 from AugurProject/make-things-immutable
KillariDev Oct 23, 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
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@
"viem": "2.38.3"
},
"scripts": {
"setup": "npm ci --ignore-scripts && npm run contracts",
"contracts": "cd solidity && npm ci --ignore-scripts && npm run compile",
"test": "cd solidity && npm run test"
"setup": "npm ci --ignore-scripts && npm run setup-contracts",
"setup-contracts": "cd solidity && npm run setup",
"compile-contracts": "cd solidity && npm run compile-contracts",
"test": "cd solidity && npm run test",
"test-peripherals": "cd solidity && npm run compile-contracts && npm run test-peripherals"
}
}
2 changes: 1 addition & 1 deletion solidity/contracts/ReputationToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import './ERC20.sol';

contract ReputationToken is ERC20 {

address public zoltar;
address public immutable zoltar;

constructor(address _zoltar) ERC20('Reputation', 'REP') {
zoltar = _zoltar;
Expand Down
49 changes: 49 additions & 0 deletions solidity/contracts/peripherals/Auction.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// SPDX-License-Identifier: UNICENSE
pragma solidity 0.8.30;
uint256 constant AUCTION_TIME = 1 weeks;

contract Auction {
mapping(address => uint256) public purchasedRep;
uint256 public totalRepPurchased;
uint256 public repAvailable;
uint256 public auctionStarted;
uint256 public ethAmountToBuy;
bool public finalized;
address immutable owner;

event Participated(address user, uint256 repAmount, uint256 ethAmount, uint256 totalRepPurchased);
event FinalizedAuction(address user, uint256 repAmount, uint256 ethAmount);
event AuctionStarted(uint256 ethAmountToBuy, uint256 repAvailable);

constructor(address _owner) {
owner = _owner;
}

function participate(uint256 repToBuy) public payable {
require(auctionStarted > 0, 'Auction needs to have started');
require(!finalized, 'Already finalized');
require(msg.value > 0, 'need to invest with eth!');
require(address(this).balance <= ethAmountToBuy, 'attempting to overfund');
require(totalRepPurchased + repToBuy <= repAvailable, 'attempt to buy too much rep');
purchasedRep[msg.sender] = repToBuy; // todo, currently anyone can buy with any price
totalRepPurchased += repToBuy;
emit Participated(msg.sender, repToBuy, msg.value, totalRepPurchased);
}

function startAuction(uint256 _ethAmountToBuy, uint256 _repAvailable) public {
require(auctionStarted == 0, 'Already started!');
auctionStarted = block.timestamp;
ethAmountToBuy = _ethAmountToBuy;
repAvailable = _repAvailable;
emit AuctionStarted(ethAmountToBuy, repAvailable);
}

function finalizeAuction() public {
//require(block.timestamp > auctionStarted + AUCTION_TIME, 'Auction needs to have ended first'); // caller checks
require(msg.sender == owner, 'Only owner can finalize');
require(!finalized, 'Already finalized');
finalized = true;
(bool sent, ) = payable(owner).call{value: address(this).balance}('');
require(sent, 'Failed to send Ether');
}
}
27 changes: 27 additions & 0 deletions solidity/contracts/peripherals/CompleteSet.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// SPDX-License-Identifier: UNICENSE
pragma solidity 0.8.30;

import '../ERC20.sol';

contract CompleteSet is ERC20 {

address public immutable securityPool;

constructor(address _securityPool) ERC20('CompleteSet', 'CS') {
securityPool = _securityPool;
}

function mint(address account, uint256 value) external {
require(msg.sender == securityPool, 'Not securityPool');
_mint(account, value);
}

function burn(address account, uint256 value) external {
require(msg.sender == securityPool, 'Not securityPool');
_burn(account, value);
}

function splitSomehow() external {
// we need to somehow split this in a way that balances are maintained
}
}
152 changes: 152 additions & 0 deletions solidity/contracts/peripherals/PriceOracleManagerAndOperatorQueuer.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
// SPDX-License-Identifier: UNICENSE
pragma solidity 0.8.30;

import { IWeth9 } from './interfaces/IWeth9.sol';
import { OpenOracle } from './openOracle/OpenOracle.sol';
import { ReputationToken } from '../ReputationToken.sol';
import { ISecurityPool } from './interfaces/ISecurityPool.sol';

// price oracle
uint256 constant PRICE_VALID_FOR_SECONDS = 1 hours;

enum OperationType {
Liquidation,
WithdrawRep,
SetSecurityBondsAllowance
}

uint256 constant gasConsumedOpenOracleReportPrice = 100000; //TODO
uint32 constant gasConsumedSettlement = 1000000; //TODO

IWeth9 constant WETH = IWeth9(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);


struct QueuedOperation {
OperationType operation;
address initiatorVault;
address targetVault;
uint256 amount;
}

contract PriceOracleManagerAndOperatorQueuer {
uint256 public pendingReportId;
uint256 public queuedPendingOperationId;
uint256 public lastSettlementTimestamp;
uint256 public lastPrice; // (REP * PRICE_PRECISION) / ETH;
ReputationToken immutable reputationToken;
ISecurityPool public immutable securityPool;
OpenOracle public immutable openOracle;

event PriceReported(uint256 reportId, uint256 price);
event ExecutetedQueuedOperation(uint256 operationId, OperationType operation, bool success);

// operation queuing
uint256 public previousQueuedOperationId;
mapping(uint256 => QueuedOperation) public queuedOperations;

constructor(OpenOracle _openOracle, ISecurityPool _securityPool, ReputationToken _reputationToken) {
reputationToken = _reputationToken;
securityPool = _securityPool;
openOracle = _openOracle;
}

function setRepEthPrice(uint256 _lastPrice) public {
require(msg.sender == address(securityPool), 'only security pool can set');
lastPrice = _lastPrice;
}

function getRequestPriceEthCost() public view returns (uint256) {// todo, probably something else
// https://github.com/j0i0m0b0o/openOracleBase/blob/feeTokenChange/src/OpenOracle.sol#L100
uint256 ethCost = block.basefee * 4 * (gasConsumedSettlement + gasConsumedOpenOracleReportPrice); // todo, probably something else
return ethCost;
}
function requestPrice() public payable {
require(pendingReportId == 0, 'Already pending request');
// https://github.com/j0i0m0b0o/openOracleBase/blob/feeTokenChange/src/OpenOracle.sol#L100
uint256 ethCost = getRequestPriceEthCost();// todo, probably something else
require(msg.value >= ethCost, 'not big enough eth bounty');

// TODO, research more on how to set these params
OpenOracle.CreateReportParams memory reportparams = OpenOracle.CreateReportParams({
exactToken1Report: 26392439800,//block.basefee * 200 / lastPrice, // initial oracle liquidity in token1
escalationHalt: reputationToken.totalSupply() / 100000, // amount of token1 past which escalation stops but disputes can still happen
settlerReward: block.basefee * 2 * gasConsumedOpenOracleReportPrice, // eth paid to settler in wei
token1Address: address(reputationToken), // address of token1 in the oracle report instance
settlementTime: 15 * 12,//~15 blocks // report instance can settle if no disputes within this timeframe
disputeDelay: 0, // time disputes must wait after every new report
protocolFee: 0, // fee paid to protocolFeeRecipient. 1000 = 0.01%
token2Address: address(WETH), // address of token2 in the oracle report instance
callbackGasLimit: gasConsumedSettlement, // gas the settlement callback must use
feePercentage: 10000, // 0.1% atm, TODO,// fee paid to previous reporter. 1000 = 0.01%
multiplier: 140, // amount by which newAmount1 must increase versus old amount1. 140 = 1.4x
timeType: true, // true for block timestamp, false for block number
trackDisputes: false, // true keeps a readable dispute history for smart contracts
keepFee: false, // true means initial reporter keeps the initial reporter reward. if false, it goes to protocolFeeRecipient
callbackContract: address(this), // contract address for settle to call back into
callbackSelector: this.openOracleReportPrice.selector, // method in the callbackContract you want called.
protocolFeeRecipient: address(0x0), // address that receives protocol fees and initial reporter rewards if keepFee set to false
feeToken: true //if true, protocol fees + fees paid to previous reporter are in tokenToSwap. if false, in not(tokenToSwap)
}); //typically if feeToken true, fees are paid in less valuable token, if false, fees paid in more valuable token

pendingReportId = openOracle.createReportInstance{value: ethCost}(reportparams);
}
function openOracleReportPrice(uint256 reportId, uint256 price, uint256, address, address) external {
require(msg.sender == address(openOracle), 'only open oracle can call');
require(reportId == pendingReportId, 'not report created by us');
pendingReportId = 0;
lastSettlementTimestamp = block.timestamp;
lastPrice = price;
emit PriceReported(reportId, lastPrice);
if (queuedPendingOperationId != 0) { // todo we maybe should allow executing couple operations?
executeQueuedOperation(queuedPendingOperationId);
queuedPendingOperationId = 0;
}
}

function isPriceValid() public view returns (bool) {
return lastSettlementTimestamp + PRICE_VALID_FOR_SECONDS > block.timestamp;
}

function requestPriceIfNeededAndQueueOperation(OperationType operation, address targetVault, uint256 amount) public payable {
require(amount > 0, 'need to do non zero operation');
previousQueuedOperationId++;
queuedOperations[previousQueuedOperationId] = QueuedOperation({
operation: operation,
initiatorVault: msg.sender,
targetVault: targetVault,
amount: amount
});
if (isPriceValid()) {
executeQueuedOperation(previousQueuedOperationId);
} else if (queuedPendingOperationId == 0) {
queuedPendingOperationId = previousQueuedOperationId;
requestPrice();
}
}

function executeQueuedOperation(uint256 operationId) public {
require(queuedOperations[operationId].amount > 0, 'no such operation or already executed');
require(isPriceValid());
// todo, we should allow these operations here to fail, but solidity try catch doesnt work inside the same contract
if (queuedOperations[operationId].operation == OperationType.Liquidation) {
try securityPool.performLiquidation(queuedOperations[operationId].initiatorVault, queuedOperations[operationId].targetVault, queuedOperations[operationId].amount) {
emit ExecutetedQueuedOperation(operationId, queuedOperations[operationId].operation, true);
} catch {
emit ExecutetedQueuedOperation(operationId, queuedOperations[operationId].operation, false);
}
} else if(queuedOperations[operationId].operation == OperationType.WithdrawRep) {
try securityPool.performWithdrawRep(queuedOperations[operationId].initiatorVault, queuedOperations[operationId].amount) {
emit ExecutetedQueuedOperation(operationId, queuedOperations[operationId].operation, true);
} catch {
emit ExecutetedQueuedOperation(operationId, queuedOperations[operationId].operation, false);
}
} else {
try securityPool.performSetSecurityBondsAllowance(queuedOperations[operationId].initiatorVault, queuedOperations[operationId].amount) {
emit ExecutetedQueuedOperation(operationId, queuedOperations[operationId].operation, true);
} catch {
emit ExecutetedQueuedOperation(operationId, queuedOperations[operationId].operation, false);
}
}
queuedOperations[operationId].amount = 0;
}
}
Loading