reimplement auction vesting
This commit is contained in:
parent
860b9d4111
commit
141211569a
60
src/RDA.sol
60
src/RDA.sol
@ -1,6 +1,7 @@
|
|||||||
pragma solidity 0.8.13;
|
pragma solidity 0.8.13;
|
||||||
|
|
||||||
import { IRDA } from "@root/interfaces/IRDA.sol";
|
import { IRDA } from "@interfaces/IRDA.sol";
|
||||||
|
import { IDelegatedVesting } from "@interfaces/IDelegatedVesting.sol";
|
||||||
|
|
||||||
import { ERC20 } from "@openzeppelin/token/ERC20/ERC20.sol";
|
import { ERC20 } from "@openzeppelin/token/ERC20/ERC20.sol";
|
||||||
import { SafeERC20 } from "@openzeppelin/token/ERC20/utils/SafeERC20.sol";
|
import { SafeERC20 } from "@openzeppelin/token/ERC20/utils/SafeERC20.sol";
|
||||||
@ -28,24 +29,7 @@ contract RDA is IRDA, ReentrancyGuard {
|
|||||||
/* @dev Auction mapping for the window index */
|
/* @dev Auction mapping for the window index */
|
||||||
mapping(bytes => uint256) public _windows;
|
mapping(bytes => uint256) public _windows;
|
||||||
|
|
||||||
struct Auction {
|
mapping(bytes => Vesting) public _vesting;
|
||||||
uint256 windowDuration; /* @dev Unix time window duration */
|
|
||||||
uint256 windowTimestamp; /* @dev Unix timestamp for window start */
|
|
||||||
uint256 startTimestamp; /* @dev Unix auction start timestamp */
|
|
||||||
uint256 endTimestamp; /* @dev Unix auction end timestamp */
|
|
||||||
uint256 duration; /* @dev Unix time auction duration */
|
|
||||||
uint256 proceeds; /* @dev Auction proceeds balance */
|
|
||||||
uint256 reserves; /* @dev Auction reserves balance */
|
|
||||||
uint256 price; /* @dev Auction origin price */
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Window {
|
|
||||||
bytes bidId; /* @dev Bid identifier */
|
|
||||||
uint256 expiry; /* @dev Unix timestamp window exipration */
|
|
||||||
uint256 price; /* @dev Window price */
|
|
||||||
uint256 volume; /* @dev Window volume */
|
|
||||||
bool processed; /* @dev Window fuflfillment state */
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @dev Conditioner to ensure an auction is active
|
* @dev Conditioner to ensure an auction is active
|
||||||
@ -137,6 +121,7 @@ contract RDA is IRDA, ReentrancyGuard {
|
|||||||
* @param w͟i͟n͟d͟o͟w͟D͟u͟r͟a͟t͟i͟o͟n͟ Uinx time window duration
|
* @param w͟i͟n͟d͟o͟w͟D͟u͟r͟a͟t͟i͟o͟n͟ Uinx time window duration
|
||||||
*/
|
*/
|
||||||
function createAuction(
|
function createAuction(
|
||||||
|
address vestingAddress,
|
||||||
address operatorAddress,
|
address operatorAddress,
|
||||||
address reserveToken,
|
address reserveToken,
|
||||||
address purchaseToken,
|
address purchaseToken,
|
||||||
@ -145,7 +130,8 @@ contract RDA is IRDA, ReentrancyGuard {
|
|||||||
uint256 startingOriginPrice,
|
uint256 startingOriginPrice,
|
||||||
uint256 startTimestamp,
|
uint256 startTimestamp,
|
||||||
uint256 endTimestamp,
|
uint256 endTimestamp,
|
||||||
uint256 windowDuration
|
uint256 windowDuration,
|
||||||
|
uint256 vestingDuration
|
||||||
) override external returns (bytes memory) {
|
) override external returns (bytes memory) {
|
||||||
bytes memory auctionId = abi.encode(
|
bytes memory auctionId = abi.encode(
|
||||||
operatorAddress,
|
operatorAddress,
|
||||||
@ -155,13 +141,8 @@ contract RDA is IRDA, ReentrancyGuard {
|
|||||||
abi.encodePacked(reserveAmount, startingOriginPrice, startTimestamp, endTimestamp, windowDuration)
|
abi.encodePacked(reserveAmount, startingOriginPrice, startTimestamp, endTimestamp, windowDuration)
|
||||||
);
|
);
|
||||||
|
|
||||||
ERC20 tokenReserve = ERC20(reserveToken);
|
|
||||||
ERC20 tokenPurchase = ERC20(purchaseToken);
|
|
||||||
|
|
||||||
Auction storage state = _auctions[auctionId];
|
Auction storage state = _auctions[auctionId];
|
||||||
|
|
||||||
uint256 auctionDuration = endTimestamp - startTimestamp;
|
|
||||||
|
|
||||||
if (state.price != 0) {
|
if (state.price != 0) {
|
||||||
revert AuctionExists();
|
revert AuctionExists();
|
||||||
}
|
}
|
||||||
@ -171,25 +152,32 @@ contract RDA is IRDA, ReentrancyGuard {
|
|||||||
if (startTimestamp < block.timestamp) {
|
if (startTimestamp < block.timestamp) {
|
||||||
revert InvalidAuctionTimestamp();
|
revert InvalidAuctionTimestamp();
|
||||||
}
|
}
|
||||||
if (tokenReserve.decimals() != tokenPurchase.decimals()){
|
if (ERC20(reserveToken).decimals() != ERC20(purchaseToken).decimals()){
|
||||||
revert InvalidTokenDecimals();
|
revert InvalidTokenDecimals();
|
||||||
}
|
}
|
||||||
if (auctionDuration < 1 days || windowDuration < 2 hours) {
|
if (endTimestamp - startTimestamp < 1 days || windowDuration < 2 hours) {
|
||||||
revert InvalidAuctionDurations();
|
revert InvalidAuctionDurations();
|
||||||
}
|
}
|
||||||
|
|
||||||
tokenReserve.safeTransferFrom(msg.sender, address(this), reserveAmount);
|
{
|
||||||
|
Vesting storage vesting = _vesting[auctionId];
|
||||||
|
|
||||||
state.windowDuration = windowDuration;
|
vesting.period = vestingDuration;
|
||||||
|
vesting.instance = vestingAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
state.duration = endTimestamp - startTimestamp;
|
||||||
state.windowTimestamp = startTimestamp;
|
state.windowTimestamp = startTimestamp;
|
||||||
state.startTimestamp = startTimestamp;
|
state.startTimestamp = startTimestamp;
|
||||||
|
state.windowDuration = windowDuration;
|
||||||
state.endTimestamp = endTimestamp;
|
state.endTimestamp = endTimestamp;
|
||||||
state.price = startingOriginPrice;
|
state.price = startingOriginPrice;
|
||||||
state.duration = auctionDuration;
|
|
||||||
state.reserves = reserveAmount;
|
state.reserves = reserveAmount;
|
||||||
|
|
||||||
emit NewAuction(auctionId, reserveToken, reserveAmount, startingOriginPrice, endTimestamp);
|
emit NewAuction(auctionId, reserveToken, reserveAmount, startingOriginPrice, endTimestamp);
|
||||||
|
|
||||||
|
ERC20(reserveToken).safeTransferFrom(msg.sender, address(this), reserveAmount);
|
||||||
|
|
||||||
return auctionId;
|
return auctionId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -451,20 +439,24 @@ contract RDA is IRDA, ReentrancyGuard {
|
|||||||
function redeem(address bidder, bytes calldata auctionId)
|
function redeem(address bidder, bytes calldata auctionId)
|
||||||
inactiveAuction(auctionId)
|
inactiveAuction(auctionId)
|
||||||
override external {
|
override external {
|
||||||
ERC20 tokenReserve = ERC20(reserveToken(auctionId));
|
Vesting storage vesting = _vesting[auctionId];
|
||||||
|
|
||||||
ERC20 tokenPurchase = ERC20(purchaseToken(auctionId));
|
ERC20 tokenPurchase = ERC20(purchaseToken(auctionId));
|
||||||
|
IDelegatedVesting vestingInstance = IDelegatedVesting(vesting.instance);
|
||||||
|
|
||||||
|
uint256 vestingTimestamp = block.timestamp + vesting.period;
|
||||||
|
|
||||||
bytes memory claimHash = _claims[bidder][auctionId];
|
bytes memory claimHash = _claims[bidder][auctionId];
|
||||||
|
|
||||||
(uint256 refund, uint256 claim) = balancesOf(claimHash);
|
|
||||||
|
|
||||||
delete _claims[bidder][auctionId];
|
delete _claims[bidder][auctionId];
|
||||||
|
|
||||||
|
(uint256 refund, uint256 claim) = balancesOf(claimHash);
|
||||||
|
|
||||||
if (refund > 0) {
|
if (refund > 0) {
|
||||||
tokenPurchase.safeTransfer(bidder, refund);
|
tokenPurchase.safeTransfer(bidder, refund);
|
||||||
}
|
}
|
||||||
if (claim > 0) {
|
if (claim > 0) {
|
||||||
tokenReserve.safeTransfer(bidder, claim);
|
vestingInstance.makeCommitment(bidder, claim, vestingTimestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
emit Claim(auctionId, claimHash);
|
emit Claim(auctionId, claimHash);
|
||||||
|
@ -12,4 +12,10 @@ interface IGovernance {
|
|||||||
|
|
||||||
function Staking() external returns (address);
|
function Staking() external returns (address);
|
||||||
|
|
||||||
|
function propose(address target, string memory description) external returns (uint256);
|
||||||
|
|
||||||
|
function castVote(uint256 proposalId, bool support) external;
|
||||||
|
|
||||||
|
function execute(uint256 proposalId) external payable;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,14 +2,48 @@ pragma solidity 0.8.13;
|
|||||||
|
|
||||||
interface IRDA {
|
interface IRDA {
|
||||||
|
|
||||||
|
struct Auction {
|
||||||
|
uint256 windowDuration; /* @dev Unix time window duration */
|
||||||
|
uint256 windowTimestamp; /* @dev Unix timestamp for window start */
|
||||||
|
uint256 startTimestamp; /* @dev Unix auction start timestamp */
|
||||||
|
uint256 endTimestamp; /* @dev Unix auction end timestamp */
|
||||||
|
uint256 duration; /* @dev Unix time auction duration */
|
||||||
|
uint256 proceeds; /* @dev Auction proceeds balance */
|
||||||
|
uint256 reserves; /* @dev Auction reserves balance */
|
||||||
|
uint256 price; /* @dev Auction origin price */
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Window {
|
||||||
|
bytes bidId; /* @dev Bid identifier */
|
||||||
|
uint256 expiry; /* @dev Unix timestamp window exipration */
|
||||||
|
uint256 price; /* @dev Window price */
|
||||||
|
uint256 volume; /* @dev Window volume */
|
||||||
|
bool processed; /* @dev Window fuflfillment state */
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Vesting {
|
||||||
|
address instance;
|
||||||
|
uint256 period;
|
||||||
|
}
|
||||||
|
|
||||||
error InvalidPurchaseVolume();
|
error InvalidPurchaseVolume();
|
||||||
|
|
||||||
|
error InvalidReserveVolume();
|
||||||
|
|
||||||
error InvalidWindowVolume();
|
error InvalidWindowVolume();
|
||||||
|
|
||||||
error InvalidWindowPrice();
|
error InvalidWindowPrice();
|
||||||
|
|
||||||
error InsufficientReserves();
|
error InsufficientReserves();
|
||||||
|
|
||||||
|
error InvalidTokenDecimals();
|
||||||
|
|
||||||
|
error InvalidAuctionDurations();
|
||||||
|
|
||||||
|
error InvalidAuctionPrice();
|
||||||
|
|
||||||
|
error InvalidAuctionTimestamp();
|
||||||
|
|
||||||
error InvalidScalarPrice();
|
error InvalidScalarPrice();
|
||||||
|
|
||||||
error WindowUnexpired();
|
error WindowUnexpired();
|
||||||
@ -18,6 +52,10 @@ interface IRDA {
|
|||||||
|
|
||||||
error AuctionExists();
|
error AuctionExists();
|
||||||
|
|
||||||
|
error AuctionActive();
|
||||||
|
|
||||||
|
error AuctionInactive();
|
||||||
|
|
||||||
function createAuction(
|
function createAuction(
|
||||||
address vestingAddress,
|
address vestingAddress,
|
||||||
address operatorAddress,
|
address operatorAddress,
|
||||||
@ -32,6 +70,10 @@ interface IRDA {
|
|||||||
uint256 vestingDuration
|
uint256 vestingDuration
|
||||||
) external returns (bytes memory);
|
) external returns (bytes memory);
|
||||||
|
|
||||||
|
function commitBid(bytes memory auctionId, uint256 price, uint256 volume) external returns (bytes memory);
|
||||||
|
|
||||||
|
function fulfillWindow(bytes memory auctionId, uint256 windowId) external;
|
||||||
|
|
||||||
function withdraw(bytes memory auctionId) external;
|
function withdraw(bytes memory auctionId) external;
|
||||||
|
|
||||||
function redeem(address bidder, bytes memory auctionId) external;
|
function redeem(address bidder, bytes memory auctionId) external;
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
pragma solidity ^0.8.1;
|
pragma solidity ^0.8.1;
|
||||||
|
|
||||||
import "@interfaces/IRelayerRegistry.sol";
|
import "@openzeppelin/token/ERC20/IERC20.sol";
|
||||||
import "@interfaces/IGovernance.sol";
|
import "@interfaces/IGovernance.sol";
|
||||||
import "@interfaces/IERC20.sol";
|
import "@interfaces/IRDA.sol";
|
||||||
|
|
||||||
import "@proprietary/Parameters.sol";
|
import "@proprietary/Parameters.sol";
|
||||||
import "@proprietary/Mock.sol";
|
import "@proprietary/Mock.sol";
|
||||||
|
Loading…
Reference in New Issue
Block a user