Created
January 4, 2021 17:20
-
-
Save aviexk/a78f72b4d302fe9b0f3ce5630b682c19 to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.7.4+commit.3f05b770.js&optimize=false&runs=200&gist=
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.7.3; | |
import 'https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v3.2.0-solc-0.7/contracts/token/ERC20/ERC20.sol'; | |
contract CollateralToken is ERC20 { | |
constructor() ERC20("METH", "METH") { | |
_setupDecimals(0); | |
_mint(0x5B38Da6a701c568545dCfcB03FcB875f56beddC4, 100000); //tokenSponser | |
_mint(0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2, 100000); //Liquidator | |
_mint(0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db, 100000); //Disputor | |
} | |
} |
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.7.3; | |
import "./SyntheticToken.sol"; | |
import "./TokenFactory.sol"; | |
import "./CollateralToken.sol"; | |
import "./Timer.sol"; | |
import "./Oracle.sol"; | |
contract FinancialContract { | |
SyntheticToken public syntheticToken; | |
TokenFactory public tokenFactory; | |
CollateralToken public collateralToken; | |
Timer public timer; | |
Oracle public oracle; | |
//store created positions | |
struct Position { | |
uint256 tokensOutstanding; | |
uint256 collateralAmount; | |
} | |
string public priceIdentifier; | |
enum ContractStatus { | |
Open, | |
Settled | |
} | |
uint256 public finalPrice; | |
ContractStatus public currentStatus; | |
mapping(address => Position) public positions; | |
uint256 public minimumNumberOfTokens; | |
uint256 public collateralRatioRequired; | |
constructor() { | |
minimumNumberOfTokens = 100; | |
tokenFactory = TokenFactory(0x8862090A79412D034d9Fb8C9DBFd3194C8D2a2EE); | |
syntheticToken = tokenFactory.createToken("SyntheticToken", "SNT"); | |
collateralToken = CollateralToken(0xC5862Ba753F3DabC4120E9803c01e0B13D7905F2); | |
timer = Timer(0x9AeB0ff23DF8c3d3a251AC31a0923419d8bCB43C); | |
oracle = Oracle(0x9C9fF5DE0968dF850905E74bAA6a17FED1Ba042a); | |
priceIdentifier = "METH/USD"; | |
currentStatus = ContractStatus.Open; | |
collateralRatioRequired = 2; | |
require(oracle.isSupportedIdentifier(priceIdentifier), "Not supported Price Identifier"); | |
} | |
//createPosition | |
function createPosition(uint256 _numberOfTokens, uint256 _collateralAmount) public { | |
require(_collateralAmount / _numberOfTokens > collateralRatioRequired, " Vellow collateral ratio"); | |
require(currentStatus == ContractStatus.Open, "Contract is not open"); | |
require(_numberOfTokens >= minimumNumberOfTokens, "Below minimum amount of tokens"); | |
Position storage currentPosition = positions[msg.sender]; | |
currentPosition.tokensOutstanding = _numberOfTokens; | |
currentPosition.collateralAmount = _collateralAmount; | |
syntheticToken.mint(msg.sender, _numberOfTokens); | |
collateralToken.transferFrom(msg.sender, address(this), _collateralAmount); | |
} | |
enum LiquidationStatus { | |
Liquidated, | |
PendingDispute, | |
DisputeSucceeded, | |
DisputeFailed | |
} | |
struct Liquidation { | |
address sponsor; | |
address liquidator; | |
uint256 liquidationTime; | |
address disputer; | |
uint256 settlementPrice; | |
uint256 collateralLocked; | |
uint256 liquidationCollateral; | |
uint256 tokensLiquidated; | |
LiquidationStatus status; | |
} | |
uint256 public numberOfLiquidations; | |
mapping(uint256 => Liquidation) public liquidations; | |
//createLiquidation | |
function createLiquidation(address _tokenSponsor) public { | |
numberOfLiquidations = numberOfLiquidations + 1; | |
Position storage positionToLiquidate = positions[_tokenSponsor]; | |
Liquidation storage newLiquidation = liquidations[numberOfLiquidations]; | |
newLiquidation.sponsor = _tokenSponsor; | |
newLiquidation.liquidator = msg.sender; | |
newLiquidation.liquidationTime = timer.getTime(); | |
newLiquidation.disputer = address(0); | |
newLiquidation.settlementPrice = 0; | |
newLiquidation.collateralLocked = positionToLiquidate.collateralAmount; | |
newLiquidation.liquidationCollateral = positionToLiquidate.collateralAmount; | |
newLiquidation.tokensLiquidated = positionToLiquidate.tokensOutstanding; | |
newLiquidation.status = LiquidationStatus.Liquidated; | |
uint256 tokensToLiquidate = positionToLiquidate.tokensOutstanding; | |
syntheticToken.transferFrom(msg.sender, address(this), tokensToLiquidate); | |
syntheticToken.burn(tokensToLiquidate); | |
collateralToken.transferFrom(msg.sender, address(this), positionToLiquidate.collateralAmount); | |
delete positions[_tokenSponsor]; | |
} | |
//disputeLiqudation | |
function disputeLiqudation(uint256 _liquidationId) public { | |
Liquidation storage liquidation = liquidations[_liquidationId]; | |
liquidation.disputer = msg.sender; | |
liquidation.settlementPrice = oracle.getPrice(priceIdentifier); | |
liquidation.collateralLocked = liquidation.collateralLocked + liquidation.liquidationCollateral; | |
collateralToken.transferFrom(msg.sender, address(this), liquidation.liquidationCollateral); | |
} | |
//settlePosition | |
function settlePosition(uint256 _liquidationId) public { | |
Liquidation storage liquidation = liquidations[_liquidationId]; | |
require((msg.sender == liquidation.disputer) || | |
(msg.sender == liquidation.liquidator) || | |
(msg.sender == liquidation.sponsor), | |
"Caller cannot withdraw rewards"); | |
uint256 tokenRedemtionValue = liquidation.tokensLiquidated * liquidation.settlementPrice; | |
uint256 requiredCollateral = tokenRedemtionValue * collateralRatioRequired; | |
bool disputeSucceeded = liquidation.liquidationCollateral >= requiredCollateral; | |
liquidation.status = disputeSucceeded ? LiquidationStatus.DisputeSucceeded : LiquidationStatus.DisputeFailed; | |
if (disputeSucceeded) { | |
collateralToken.transfer(liquidation.disputer, liquidation.collateralLocked); | |
} else { | |
collateralToken.transfer(liquidation.liquidator, liquidation.collateralLocked); | |
} | |
delete liquidations[_liquidationId]; | |
} | |
function settle() public { | |
currentStatus = ContractStatus.Settled; | |
finalPrice = oracle.getPrice(priceIdentifier); | |
} | |
} |
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.7.3; | |
contract Oracle { | |
//save priceidentifiers - eth/usd, btc/usd | |
mapping(string => uint256) private prices; | |
//make identifiers supported | |
mapping(string => bool) private supportedIdentifiers; | |
function setPrice(string memory _identifier, uint256 _price) public { | |
require(isSupportedIdentifier(_identifier), "Identifier not supported"); | |
prices[_identifier] = _price; | |
} | |
function getPrice(string memory _identifier) public view returns (uint256) { | |
return prices[_identifier]; | |
} | |
function addIdentifier(string memory _identifier) public { | |
supportedIdentifiers[_identifier] = true; | |
} | |
function isSupportedIdentifier(string memory _identifier) public view returns (bool) { | |
return supportedIdentifiers[_identifier]; | |
} | |
} |
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.7.3; | |
import 'https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v3.2.0-solc-0.7/contracts/token/ERC20/ERC20.sol'; | |
contract SyntheticToken is ERC20 { | |
constructor(string memory _tokenName, string memory _tokenSymbol) | |
ERC20(_tokenName, _tokenSymbol) | |
{ | |
_setupDecimals(0); | |
} | |
function mint(address _recipient, uint256 _value) public returns (bool) { | |
_mint(_recipient, _value); | |
return true; | |
} | |
function burn(uint256 _value) public { | |
_burn(msg.sender, _value); | |
} | |
} |
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.7.3; | |
contract Timer { | |
uint256 private currentTime; | |
constructor() { | |
currentTime = 0; | |
} | |
function setTime(uint256 _newTime) public{ | |
currentTime = _newTime; | |
} | |
function getTime() public view returns (uint256) { | |
return currentTime; | |
} | |
} |
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.7.3; | |
import './SyntheticToken.sol'; | |
contract TokenFactory { | |
function createToken(string memory _name, string memory _symbol) public returns (SyntheticToken) { | |
SyntheticToken newSyntheticToken = new SyntheticToken(_name, _symbol); | |
return newSyntheticToken; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment