Instantly share code, notes, and snippets.
Forked from justinbarry/WrappedShareTokenFactory.sol
Last active
February 12, 2021 05:06
-
Star
(0)
0
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save pgebheim/3d4ece4ca3d3c789d2bdf8e309021f8e 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
ragma solidity 0.5.15; | |
pragma experimental ABIEncoderV2; | |
import "ROOT/trading/wrappedShareToken/WrappedShareToken.sol"; | |
import 'ROOT/para/interfaces/IParaShareToken.sol'; | |
import 'ROOT/libraries/TokenId.sol'; | |
/** | |
* @dev This is a factory that creates Wrappers around ERC1155 shareTokens generated by Augur | |
* @author yashnaman | |
* as shares on outcomes of a markets. | |
* For every outcome there will be one wrapper. | |
*/ | |
contract WrappedShareTokenFactory { | |
IParaShareToken public shareToken; | |
IERC20 public cash; | |
mapping(uint256 => address) public wrappers; | |
event WrapperCreated(uint256 indexed tokenId, address tokenAddress, string symbol); | |
/**@dev sets value for {shareToken} and {cash} | |
* @param _shareToken address of shareToken associated with a augur universe | |
*/ | |
constructor(IParaShareToken _shareToken, IERC20 _cash) public { | |
shareToken = _shareToken; | |
cash = _shareToken.cash(); | |
} | |
/**@dev creates new ERC20 wrappers for a outcome of a market | |
*@param _tokenId token id associated with a outcome of a market | |
*@param _name a descriptive name mentioning market and outcome | |
*@param _symbol symbol for the ERC20 wrapper | |
*@param decimals decimals for the ERC20 wrapper | |
*/ | |
function createWrappedShareToken( | |
uint256 _tokenId, | |
string memory _symbol | |
) public returns (WrappedShareToken) { | |
address _wrappedShareTokenAddress = calculateShareTokenAddress( | |
_tokenId, | |
_symbol, | |
); | |
if(_wrappedShareTokenAddress.exists()) { | |
return WrappedShareToken(_wrappedShareTokenAddress); | |
} | |
{ | |
bytes32 _salt = keccak256(abi.encodePacked(shareToken, cash,_tokenId, _symbol, _decimals)); | |
bytes memory _code = abi.encodePacked(type(WrappedShareToken).creationCode); | |
assembly { | |
_wrappedShareTokenAddress := create2(0x0, add(_code, 0x20), mload(_code), _salt); | |
if iszero(extcodesize(_code)) { revert(0,0) } | |
} | |
} | |
// Wrapped Share Token has to be Initializable -- see AugurWallet.sol | |
WrappedShareToken _wrappedShareToken = WrappedShareToken(_wrappedShareTokenAddress); | |
_wrappedShareToken.initialize( | |
shareToken, | |
cash, | |
_tokenId, | |
_symbol | |
); | |
emit WrapperCreated(_tokenId, address(WrappedShareToken), _symbol); | |
return _wrappedShareToken; | |
} | |
/**@dev creates new ERC20 wrappers for multiple tokenIds*/ | |
function createWrappedShareTokens( | |
uint256[] memory _tokenIds, | |
string[] memory _symbols, | |
) public returns (addresss[] memory _wrappedShareTokens){ | |
require( | |
_tokenIds.length == _names.length && | |
_tokenIds.length == _symbols.length | |
); | |
_wrappedShareToken = new address[](_tokenIds.length); | |
for (uint256 i = 0; i < _tokenIds.length; i++) { | |
_wrappedShareToken[i] = createWrappedShareToken(_tokenIds[i], _symbols[i]); | |
} | |
} | |
/**@dev A function that wraps ERC1155s shareToken into ERC20s | |
* Requirements: | |
* | |
* - msg.sender has setApprovalForAll to this contract | |
* @param _tokenId token id associated with a outcome of a market | |
* @param _account account the newly minted ERC20s will go to | |
* @param _amount amount of tokens to be wrapped | |
*/ | |
function wrapTokens( | |
address _tokenId, | |
address _account, | |
uint256 _amount | |
) public { | |
WrappedShareToken WrappedShareToken = WrappedShareToken(wrappers[_tokenId]); | |
shareToken.unsafeTransferFrom( | |
msg.sender, | |
address(WrappedShareToken), | |
_tokenId, | |
_amount | |
); | |
WrappedShareToken.wrapTokens(_account, _amount); | |
} | |
/**@dev A function that burns ERC20s and gives back ERC1155s | |
* Requirements: | |
* | |
* - msg.sender has more than _amount of ERC20 tokens associated with _tokenId. | |
* - if the market has finalized then it is advised that you call claim() on WrappedShareToken | |
* contract associated with the winning outcome | |
* @param _tokenId token id associated with a outcome of a market | |
* @param _amount amount of tokens to be unwrapped | |
*/ | |
function unWrapTokens(uint256 _tokenId, string memory _symbol, uint256 _amount) public { | |
WrappedShareToken _wrappedShareToken = WrappedShareToken(calculateShareTokenAddress(_tokenId, _symbol)); | |
WrappedShareToken.unWrapTokens(msg.sender, _amount); | |
} | |
/**@dev wraps multiple tokens */ | |
function wrapMultipleTokens( | |
uint256[] memory _tokenIds, | |
address _account, | |
uint256[] memory _amounts | |
) public { | |
for (uint256 i = 0; i < _tokenIds.length; i++) { | |
wrapTokens(_tokenIds[i], _account, _amounts[i]); | |
} | |
} | |
/**@dev unwraps multiple tokens */ | |
function unWrapMultipleTokens( | |
uint256[] memory _tokenIds, | |
uint256[] memory _amounts | |
) public { | |
for (uint256 i = 0; i < _tokenIds.length; i++) { | |
unWrapTokens(_tokenIds[i], _amounts[i]); | |
} | |
} | |
/**@dev get the address for a particular WrappedShareToken | |
*@param _tokenId token id associated with a outcome of a market | |
*@param _name a descriptive name mentioning market and outcome | |
*@param _symbol symbol for the ERC20 wrapper | |
*@param decimals decimals for the ERC20 wrapper | |
*/ | |
function calculateShareTokenAddress( | |
uint256 _tokenId, | |
string memory _symbol, | |
) public view returns (address) { | |
bytes1 _const = 0xff; | |
bytes32 _salt = keccak256(abi.encodePacked(shareToken, cash, _tokenId, _symbol)); | |
return address(uint160(uint256(keccak256(abi.encodePacked( | |
_const, | |
address(this), | |
_salt, | |
keccak256(abi.encodePacked(type(WrappedShareToken).creationCode)) | |
))))); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment