-
-
Save transmissions11/485a6e2deb89236202bd2f59796262fd to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import "./VRGDAC.sol"; | |
import "./GameToken.sol"; | |
import "solmate/tokens/ERC20.sol"; | |
import "solmate/auth/Owned.sol"; | |
contract ExchangePort is VRGDAC, Owned(msg.sender) { | |
// THIS SHIT IS GETTING CHEAPER OVER TIME!!! | |
GameToken public X; | |
GameToken public Y; | |
constructor(int256 _targetPrice, int256 _perTimeUnit, int256 _priceDecayPercent, GameToken _X, GameToken _Y) | |
VRGDAC(_targetPrice, _perTimeUnit, _priceDecayPercent) | |
{ | |
X = _X; | |
Y = _Y; | |
} | |
uint256 startTime; | |
function setStartTime(uint256 _startTime) public onlyOwner { | |
startTime = _startTime; | |
} | |
int256 emittedXWad; | |
function buyX(address guy, uint256 amount) public onlyOwner { | |
int256 spentY = buyXQuote(amount); | |
Y.burn(guy, uint256(spentY)); | |
X.mint(guy, amount); | |
emittedXWad += int256(amount); | |
} | |
function sellX(address guy, uint256 amount) public onlyOwner { | |
int256 gainedY = sellXQuote(amount); | |
X.burn(guy, amount); | |
Y.mint(guy, uint256(gainedY)); | |
emittedXWad -= int256(amount); | |
} | |
function buyY(address guy, uint256 amount) public onlyOwner { | |
int256 spentX = buyYQuote(amount); | |
X.burn(guy, uint256(spentX)); | |
Y.mint(msg.sender, amount); | |
emittedXWad -= int256(spentX); | |
} | |
function sellY(address guy, uint256 amount) public onlyOwner { | |
int256 gainedX = sellYQuote(amount); | |
Y.burn(guy, amount); | |
X.mint(guy, uint256(gainedX)); | |
emittedXWad += int256(gainedX); | |
} | |
function buyXQuote(uint256 amount) public view returns (int256 spentY) { | |
return xToY({ | |
timeSinceStart: int256(block.timestamp - startTime) * 1e18, | |
sold: emittedXWad, | |
amount: int256(amount) | |
}); | |
} | |
function sellXQuote(uint256 amount) public view returns (int256 gainedY) { | |
return -xToY({timeSinceStart: int256(block.timestamp - startTime) * 1e18, sold: emittedXWad, amount: -int256(amount)}); | |
} | |
function buyYQuote(uint256 amount) public view returns (int256 spentX) { | |
return -yToX({timeSinceStart: int256(block.timestamp - startTime) * 1e18, sold: emittedXWad, amount: -int256(amount)}); | |
} | |
function sellYQuote(uint256 amount) public view returns (int256 gainedX) { | |
return yToX({ | |
timeSinceStart: int256(block.timestamp - startTime) * 1e18, | |
sold: emittedXWad, | |
amount: int256(amount) | |
}); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: MIT | |
pragma solidity >=0.8.0; | |
import { | |
wadExp, | |
wadLn, | |
wadMul, | |
wadDiv, | |
unsafeWadMul, | |
unsafeWadDiv, | |
toWadUnsafe, | |
wadPow | |
} from "solmate/utils/SignedWadMath.sol"; | |
/// @title Continuous Variable Rate Gradual Dutch Auction | |
/// @author transmissions11 <t11s@paradigm.xyz> | |
/// @author FrankieIsLost <frankie@paradigm.xyz> | |
/// @author Dan Robinson <dan@paradigm.xyz> | |
/// @notice Sell tokens roughly according to an issuance schedule. | |
contract VRGDAC { | |
/*////////////////////////////////////////////////////////////// | |
VRGDA PARAMETERS | |
//////////////////////////////////////////////////////////////*/ | |
int256 public immutable targetPrice; | |
int256 public immutable perTimeUnit; | |
int256 public immutable decayConstant; | |
int256 public immutable priceDecayPercent; | |
/// @notice Sets target price and per time unit price decay for the VRGDA. | |
/// @param _targetPrice The target price for a token if sold on pace, scaled by 1e18. | |
/// @param _perTimeUnit The number of tokens to target selling in 1 full unit of time, scaled by 1e18. | |
/// @param _priceDecayPercent The percent price decays per unit of time with no sales, scaled by 1e18. | |
constructor(int256 _targetPrice, int256 _perTimeUnit, int256 _priceDecayPercent) { | |
targetPrice = _targetPrice; | |
perTimeUnit = _perTimeUnit; | |
priceDecayPercent = _priceDecayPercent; | |
decayConstant = wadLn(1e18 - _priceDecayPercent); | |
// The decay constant must be negative for VRGDAs to work. | |
require(decayConstant < 0, "NON_NEGATIVE_DECAY_CONSTANT"); | |
} | |
/*////////////////////////////////////////////////////////////// | |
PRICING LOGIC | |
//////////////////////////////////////////////////////////////*/ | |
function xToY(int256 timeSinceStart, int256 sold, int256 amount) public view virtual returns (int256) { | |
unchecked { | |
return pIntegral(timeSinceStart, sold + amount) - pIntegral(timeSinceStart, sold); | |
} | |
} | |
function yToX(int256 timeSinceStart, int256 sold, int256 amount) public view virtual returns (int256) { | |
unchecked { | |
return wadMul( | |
-wadDiv( | |
wadLn(1e18 - wadMul(amount, wadDiv(decayConstant, wadMul(perTimeUnit, p(timeSinceStart, sold))))), | |
decayConstant | |
), | |
perTimeUnit | |
); | |
} | |
} | |
function pIntegral(int256 timeSinceStart, int256 sold) internal view returns (int256) { | |
return wadDiv( | |
-wadMul( | |
wadMul(targetPrice, perTimeUnit), | |
wadPow(1e18 - priceDecayPercent, timeSinceStart - unsafeWadDiv(sold, perTimeUnit)) | |
), | |
decayConstant | |
); | |
} | |
function p(int256 timeSinceStart, int256 sold) internal view returns (int256) { | |
return wadMul(targetPrice, wadPow(1e18 - priceDecayPercent, timeSinceStart - unsafeWadDiv(sold, perTimeUnit))); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment