Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- pragma solidity ^ 0.6.3;
- contract Prism{
- address address0 = address(0);
- mapping(address => PyramidProxy) public proxy;
- mapping(address => address) gateway; // masternode
- mapping(address => uint256) pocket;
- mapping(address => uint256) upline;
- mapping(address => address) minecart;
- uint public bondsIN = 100000000e12; // 100 million bonds.
- uint public bondsOUT = 100000000e12;
- PyramidContract public pyramidContract;
- ERC20 public resolveToken;
- address public pyramidAddress;
- address public resolveAddress;
- ColorBonds public colorBonds;
- ColorResolve public colorResolve;
- address public lastValidGateway;
- address public communityResolve;
- uint public gatewayRequirement;
- constructor(address _pyramidAddress) public{
- pyramidAddress = _pyramidAddress;
- pyramidContract = PyramidContract( pyramidAddress );
- resolveToken = pyramidContract.resolveToken();
- resolveAddress = address( resolveToken );
- colorBonds = new ColorBonds( pyramidAddress );
- colorResolve = new ColorResolve( resolveAddress );
- communityResolve = msg.sender;
- lastValidGateway = communityResolve;
- }
- function totalColorBonds() public view returns (uint){
- return bondsIN - bondsOUT;
- }
- event Buy( address indexed addr, uint256 spent, uint256 bonds, uint red, uint green, uint blue);
- function buy(address addr, uint _red, uint _green, uint _blue, address gatewayAddress) payable public returns(uint bondsCreated){
- ensureInitiation(msg.sender, gatewayAddress);
- return buy( addr, msg.value, _red, _green, _blue, true );
- }
- function ensureInitiation(address addr, address gatewayAddress) internal{
- if( gateway[addr] == address0){
- colorResolve.initiateVotingAccount(addr);
- if( checkGatewayRequirement(gatewayAddress) ){
- gateway[addr] = gatewayAddress;
- }else{
- if( checkGatewayRequirement(lastValidGateway) ){
- gateway[addr] = lastValidGateway;
- }else{
- gateway[addr] = communityResolve;
- }
- }
- }
- }
- function buy(address addr, uint ETH, uint _red, uint _green, uint _blue, bool regularBuy) internal returns(uint bondsCreated){
- if(_red>1e12) return _red = 1e12;
- if(_green>1e12) return _green = 1e12;
- if(_blue>1e12) return _blue = 1e12;
- uint fee;
- if( regularBuy ){
- fee = colorFee( msg.value );
- }
- uint eth4Bonds = ETH - fee;
- uint createdBonds = ensureProxy(addr).buy.value( eth4Bonds )();
- bondsIN += createdBonds;
- upline[ addr ] += fee;
- colorBonds.addColor(addr, createdBonds, _red, _green, _blue);
- pushMinecart( addr );
- if( checkGatewayRequirement( addr ) ){
- lastValidGateway = addr;
- }
- if( regularBuy ){
- emit Buy( addr, eth4Bonds, createdBonds, _red, _green, _blue );
- }
- return createdBonds;
- }
- event Sell( address indexed addr,uint cashout, uint256 bondsSold, uint256 resolves, uint initialInput, uint mintedColorWeight);
- function sell(uint amountToSell) public returns(uint eth, uint resolvesMinted, uint initialInput, uint mintedColorWeight){
- address sender = msg.sender;
- uint bondsBefore = colorBonds.balanceOf(sender);
- uint[] memory RGB = new uint[](3);
- (RGB[0], RGB[1], RGB[2]) = colorBonds.RGB_Ratio(sender);
- (uint numEthers, uint mintedResolves, uint initialInput_ETH, uint destroyedColoredBonds) = proxy[sender].sell(amountToSell);
- bondsOUT += destroyedColoredBonds;
- mintedColorWeight = mintedResolves * destroyedColoredBonds / amountToSell;
- colorResolve.addColor(sender, mintedColorWeight, RGB[0]*1e6, RGB[1]*1e6, RGB[2]*1e6 );
- colorResolve.updateVotingWeight(sender, mintedColorWeight);
- emit Sell(sender, numEthers, amountToSell, mintedResolves, initialInput_ETH, mintedColorWeight);
- colorBonds.thinColor(sender, bondsBefore - amountToSell, bondsBefore );
- return (numEthers, mintedResolves, initialInput_ETH, mintedColorWeight);
- }
- event Withdraw( address indexed addr, uint256 earnings, uint256 dissolved );
- function withdraw(uint amount) public returns(uint){
- address payable sender = msg.sender;
- uint dissolvedResolves = proxy[sender].withdraw(amount);
- colorResolve.colorShift(pyramidAddress, address(0), dissolvedResolves);
- uint earned = pocket[sender];
- pocket[sender] = 0;
- pushMinecart(sender);
- (bool success, ) = sender.call.value(earned)("");
- require(success, "Transfer failed.");
- emit Withdraw( sender, amount, dissolvedResolves);
- return dissolvedResolves;
- }
- event Reinvest( address indexed addr, uint256 coreEarningsReinvested , uint256 affiliateEarningsSpent, uint256 bondsCreated, uint256 dissolved );
- function reinvest( uint amount ) public returns(uint,uint){
- address sender = msg.sender;
- C
- (uint _red, uint _green, uint _blue) = colorBonds.RGB_Ratio();
- uint createdBonds;
- uint dissolvedResolves;
- uint affiliateEarnings = pocket[sender];
- require( affiliateEarnings >= 0.000001 ether || amount > 0 );
- uint pockBonds;
- if (affiliateEarnings >= 0.000001 ether){
- pocket[sender] = 0;
- pockBonds = buy( sender, affiliateEarnings, _red, _green, _blue, false );
- }
- if(amount>0){
- (createdBonds, dissolvedResolves) = proxy[sender].reinvest( amount );
- colorResolve.colorShift(pyramidAddress, address(0), dissolvedResolves);
- bondsIN += createdBonds;
- }
- emit Reinvest( sender, amount, affiliateEarnings, createdBonds + pockBonds, dissolvedResolves);
- pushMinecart(sender);
- return (createdBonds, dissolvedResolves);
- }
- event Stake( address indexed addr, uint256 amountStaked );
- function stake(uint amountToStake) public{
- address sender = msg.sender;
- colorResolve.colorShift( sender, pyramidAddress, amountToStake );
- proxy[sender].stake( amountToStake );
- pushMinecart(sender);
- minecart[sender] = sender;
- emit Stake(sender, amountToStake);
- /* a little bit of economic chaos theory going on here.
- since most people at the edges will have most of the resolves,
- they will be the most likely to stake. you don't need as many
- minecart pushers near the top of the affiliate system */
- }
- event Unstake( address indexed addr, uint256 pulledResolves, uint256 forfeiture );
- function unstake(uint amountToUnstake) public returns (uint){
- address sender = msg.sender;
- colorResolve.colorShift( pyramidAddress, sender, amountToUnstake );
- uint forfeiture = proxy[sender].unstake( amountToUnstake );
- pushMinecart(sender);
- minecart[sender] = sender;
- emit Unstake( sender, amountToUnstake, forfeiture);
- return forfeiture;
- }
- function auth(address addr) public view returns(bool){
- return (addr == address(colorResolve) || addr == address(colorBonds) );
- }
- function ensureProxy(address addr) internal returns (PyramidProxy){
- if( address( proxy[addr] ) == address0 ){
- PyramidProxy prox = new PyramidProxy( addr );
- proxy[addr] = prox;
- }
- return proxy[addr];
- }
- function external_ensureProxy(address addr) external returns (PyramidProxy){
- require( auth(msg.sender) );
- return ensureProxy(addr);
- }
- function colorFee(uint eth) public view returns(uint){
- return eth * ( bondsIN - bondsOUT ) / bondsIN;
- //Dwindling Color Fee: ( bondsIN - bondsOUT ) / bondsIN
- }
- function weighUp(address payer, uint fee) public view returns(uint){
- //This is "how much can the Gateway can bully the system into benefitting more from the downline".
- //2 to 3 parties "weigh up". Payer & communityResolve vs. Gateway
- //2 parties, if one of them is already the community resolve
- //3 parties if the payer needs "help". Having the community resolve to "step in"
- address gateKeeper = gateway[payer];
- uint gateWeight = resolveToken.balanceOf( address( proxy[gateKeeper] ) );
- uint communityWeight = resolveToken.balanceOf( address( proxy[communityResolve] ) );
- uint totalOfComparingWeights = resolveToken.balanceOf( address( proxy[payer] ) ) + gateWeight + communityWeight;
- if( payer == communityResolve || gateKeeper == communityResolve ){
- totalOfComparingWeights -= communityWeight;
- }
- if(totalOfComparingWeights == 0)
- return 0;
- return fee * gateWeight / totalOfComparingWeights;
- }
- function checkGatewayRequirement(address addr) internal view returns(bool){
- return ( resolveToken.balanceOf(addr) >= gatewayRequirement && addr != address0 && addr != msg.sender ) || addr == communityResolve;
- }
- event Snatch(address snatched, address snatcher);
- function pushMinecart(address addr) public{
- address gate = gateway[addr];
- if( gate != address0 ){
- // ensure a valid gateway
- // a lacking gateway gets their affiliates snatched
- if( !checkGatewayRequirement(gate) ){
- if( checkGatewayRequirement(lastValidGateway) ){
- gateway[addr] = lastValidGateway;
- }else{
- gateway[addr] = communityResolve;
- }
- emit Snatch(addr, gateway[addr]);
- }
- // if the minecart is at the center of gravity (the communityResolve) then reset its position
- address nextCartPosition = ( minecart[addr] == communityResolve) ? addr : gateway[ minecart[addr] ];
- pushPipeline(addr);// always pushes funds from the user's own position of the downline
- pushPipeline(nextCartPosition);// the minecart pushes up through the hierarchy
- }
- }
- function ensureUpdatedVotes(address voter) public {
- address candidate = colorResolve.votingForCR(voter);
- if( colorResolve.votesForCR(candidate) > colorResolve.votesForCR(communityResolve) ){
- communityResolve = candidate;
- }
- uint GR_votingFor = colorResolve.votingForGR(voter);
- if( colorResolve.votesForGR(GR_votingFor) > colorResolve.votesForGR(gatewayRequirement) ){
- gatewayRequirement = GR_votingFor;
- }
- }
- event PipelinePush(address pushingPosition, address gateKeeper, uint amountPushed, uint amountPaid);
- function pushPipeline(address addr) internal{
- uint ETH = upline[addr];
- uint ethPayingOut = weighUp(addr, ETH);
- pocket[addr] += ethPayingOut;
- uint ethGoingUp = ETH - ethPayingOut;
- if( ethGoingUp < 0.000001 ether ){
- upline[ gateway[addr] ] = ethGoingUp;
- }else{
- pocket[ communityResolve ] = ethGoingUp;
- }
- upline[addr] = 0;
- emit PipelinePush(addr, gateway[addr], ETH, ethPayingOut);
- }
- function fundPipeline(address addr) payable public{
- upline[addr] += msg.value;
- pushMinecart(addr);
- }
- function fundCommunityResolve() payable public{
- pocket[communityResolve] += msg.value;
- }
- function isContract(address _addr) internal view returns (bool is_contract) {
- uint length = 0;
- assembly {
- //retrieve the size of the code on target address, this needs assembly
- length := extcodesize(_addr)
- }
- if(length>0) {
- return true;
- }else {
- return false;
- }
- }
- }
- contract PyramidProxy{
- Prism prism;
- address public THIS = address(this);
- address payable owner;
- uint coloredBonds;
- constructor( address _owner ) public{
- prism = Prism(msg.sender);
- owner = address( uint160( _owner ) );
- }
- modifier authOnly{
- require(msg.sender == address(prism) || prism.auth(msg.sender) );
- _;
- }
- function buy() payable external authOnly() returns(uint){
- uint createdBonds = prism.pyramidContract().fund.value( msg.value )();
- coloredBonds += createdBonds;
- return createdBonds;
- }
- function sell(uint amount) external authOnly() returns (uint,uint,uint,uint destroyedColoredBonds){
- destroyedColoredBonds = amount * coloredBonds / prism.colorBonds().balanceOf(owner);
- coloredBonds -= destroyedColoredBonds;
- (uint ETH, uint resolves, uint initialInput_ETH) = prism.pyramidContract().sellBonds(amount);
- return ( ETH - prism.colorFee( ETH ), resolves, initialInput_ETH, destroyedColoredBonds );
- }
- function transfer(address _to, uint _value) external authOnly(){
- ERC20( ColorToken(msg.sender).asset() ).transfer( address( prism.external_ensureProxy(_to) ), _value );
- }
- function withdraw(uint amount) external authOnly() returns(uint){
- uint dissolvedResolves = prism.pyramidContract().withdraw( amount );
- return dissolvedResolves;
- }
- function reinvest(uint amount) external authOnly() returns(uint,uint){
- return prism.pyramidContract().reinvestEarnings( amount );
- }
- function stake(uint amount) external authOnly(){
- prism.resolveToken().transfer( prism.pyramidAddress(), amount );
- }
- function stake2(uint amount) external{
- prism.resolveToken().transfer( prism.pyramidAddress(), amount );
- }
- function unstake(uint amount) external authOnly() returns(uint){
- return prism.pyramidContract().pullResolves( amount );
- }
- function unwrapTokens(uint amountToUnwrap) external authOnly(){
- ERC20( ColorToken(msg.sender).asset() ).transfer( owner, amountToUnwrap );
- }
- fallback () payable external {
- uint ETH = msg.value;
- uint fee = prism.colorFee( ETH );
- prism.fundPipeline.value( fee )( owner );
- (bool success, ) = owner.call.value( ETH - fee )("");
- require(success, "Transfer failed.");
- }
- }
- abstract contract ERC20{
- function balanceOf(address _owner) public view virtual returns (uint256 balance);
- function transfer(address _to, uint256 _value) public virtual returns (bool);
- }
- contract ColorToken is ERC20{
- address public asset;
- mapping(address => uint256) public C;
- mapping(address => uint256) public red;
- mapping(address => uint256) public green;
- mapping(address => uint256) public blue;
- uint public totalWeight;
- mapping(address => mapping(address => uint)) approvals;
- Prism prism;
- constructor(address _asset) public{
- prism = Prism(msg.sender);
- asset = _asset;
- }
- modifier authOnly{
- require(msg.sender == address(prism) || prism.auth(msg.sender) );
- _;
- }
- event UnwrapTokens( address indexed addr, uint256 amountUnwrapped);
- function unwrapTokens(uint _value) public {
- address sender = msg.sender;
- uint total = balanceOf(sender);
- this.thinColor(sender, total - _value, total);
- prism.proxy(sender).unwrapTokens( _value );
- emit UnwrapTokens( sender, _value );
- }
- // Function that is called when a user or another contract wants to transfer funds.
- function addColor(address addr, uint color, uint _red, uint _green, uint _blue) public authOnly(){
- red[addr] += _red * color;
- green[addr] += _green * color;
- blue[addr] += _blue * color;
- C[addr] += color;
- }
- function thinColor(address addr, uint newWeight, uint oldWeight) public authOnly(){
- (red[addr], green[addr], blue[addr], C[addr]) = RGB_scale( addr, newWeight, oldWeight);
- }
- function RGB_Ratio() public view returns(uint,uint,uint){
- return RGB_Ratio(msg.sender);
- }
- function RGB_Ratio(address addr) public view returns(uint,uint,uint){
- uint coloredWeight = C[addr];
- if (coloredWeight==0){
- return (0,0,0);
- }
- return ( red[addr]/coloredWeight, green[addr]/coloredWeight, blue[addr]/coloredWeight);
- }
- function RGB_scale(address addr, uint numerator, uint denominator) internal view returns(uint,uint,uint,uint){
- return (red[addr] * numerator / denominator, green[addr] * numerator / denominator, blue[addr] * numerator / denominator, C[addr] * numerator / denominator );
- }
- function balanceOf(address addr) public view override returns(uint){
- return ERC20( asset ).balanceOf( address( prism.proxy(addr) ) );
- }
- // Function that is called when a user or another contract wants to transfer funds.
- function transfer(address _to, uint _value, bytes memory _data) public returns (bool) {
- if( Common.isContract(_to) ){
- return transferToContract(_to, _value, _data);
- }else{
- return transferToAddress(_to, _value, _data);
- }
- }
- // Standard function transfer similar to ERC20 transfer with no _data.
- // Added due to backwards compatibility reasons .
- function transfer(address _to, uint _value) public override returns (bool) {
- //standard function transfer similar to ERC20 transfer with no _data
- //added due to backwards compatibility reasons
- bytes memory empty;
- if(Common.isContract(_to)){
- return transferToContract(_to, _value, empty);
- }else{
- return transferToAddress(_to, _value, empty);
- }
- }
- //function that is called when transaction target is an address
- function transferToAddress(address _to, uint _value, bytes memory _data) private returns (bool) {
- moveTokens(msg.sender, _to, _value);
- return true;
- }
- //function that is called when transaction target is a contract
- function transferToContract(address _to, uint _value, bytes memory _data) private returns (bool) {
- moveTokens(msg.sender, _to, _value);
- ERC223ReceivingContract reciever = ERC223ReceivingContract(_to);
- reciever.tokenFallback(msg.sender, _value, _data);
- return true;
- }
- function moveTokens(address _from, address _to, uint _amount) internal virtual{
- prism.external_ensureProxy(_to);
- this.colorShift(_from, _to, _amount);
- prism.proxy(_from).transfer(_to, _amount);
- }
- function colorShift(address _from, address _to, uint amountOfTokensShifting) public authOnly() virtual returns(uint){
- uint totalTokens;
- if( _from == prism.pyramidAddress() && asset == prism.resolveAddress() ){
- totalTokens = ERC20(asset).balanceOf(_from);
- //if you do a "hard transfer" of colorBonds to the pyramid. it's going to send those bonds to the Pyramid's Proxy.
- }else{
- totalTokens = ERC20(asset).balanceOf( address( prism.proxy(_from) ) );
- }
- (uint red_ratio, uint green_ratio, uint blue_ratio, uint colorWeight) = RGB_scale( _from, amountOfTokensShifting, totalTokens );
- red[_from] -= red_ratio;
- green[_from] -= green_ratio;
- blue[_from] -= blue_ratio;
- C[_from] -= colorWeight;
- red[_to] += red_ratio;
- green[_to] += green_ratio;
- blue[_to] += blue_ratio;
- C[_to] += colorWeight;
- return colorWeight;
- }
- function allowance(address src, address guy) public view returns (uint) {
- return approvals[src][guy];
- }
- function transferFrom(address src, address dst, uint amount) public returns (bool){
- address sender = msg.sender;
- require(approvals[src][sender] >= amount);
- if (src != sender) {
- approvals[src][sender] -= amount;
- }
- moveTokens(src,dst,amount);
- return true;
- }
- event Approval(address indexed src, address indexed guy, uint amount);
- function approve(address guy, uint amount) public returns (bool) {
- address sender = msg.sender;
- approvals[sender][guy] = amount;
- emit Approval( sender, guy, amount );
- return true;
- }
- }
- contract ColorResolve is ColorToken{
- string public name = "Color";
- string public symbol = "RGB";
- uint8 constant public decimals = 18;
- mapping(address => address) public votingForCR;
- mapping(address => uint256) public votesForCR;
- mapping(address => uint) public votingForGR;
- mapping(uint => uint256) public votesForGR;
- constructor(address _asset) public ColorToken(_asset){}
- function colorShift(address _from, address _to, uint _amount) public authOnly() override returns(uint){
- uint colorWeight = super.colorShift(_from, _to, _amount);
- votesForGR[ votingForGR[_from] ] -= colorWeight;
- votesForCR[ votingForCR[_from] ] -= colorWeight;
- votesForGR[ votingForGR[_to] ] += colorWeight;
- votesForCR[ votingForCR[_to] ] += colorWeight;
- prism.ensureUpdatedVotes(_to);
- return colorWeight;
- }
- function initiateVotingAccount(address voter) external authOnly(){
- votingForCR[voter] = prism.communityResolve();
- votingForGR[voter] = prism.gatewayRequirement();
- }
- function updateVotingWeight(address voter, uint weight) external authOnly(){
- votesForCR[ votingForCR[voter] ] += weight;
- votesForGR[ votingForGR[voter] ] += weight;
- prism.ensureUpdatedVotes(voter);
- }
- function setVotingForCR(address candidate) public {
- address voter = msg.sender;
- //Contracts can't vote for anyone. Because then people would just evenly split the pool fund most of the time
- uint voteWeight = C[voter];
- votesForCR[ votingForCR[voter] ] -= voteWeight;
- votingForCR[ voter ] = candidate;
- votesForCR[ candidate ] += voteWeight;
- prism.ensureUpdatedVotes(voter);
- }
- function setVotingForGR(uint MR_votingFor) public {
- address voter = msg.sender;
- uint voteWeight = C[voter];
- votesForGR[ votingForGR[voter] ] -= voteWeight;
- votingForGR[ voter ] = MR_votingFor;
- votesForGR[ MR_votingFor ] += voteWeight;
- prism.ensureUpdatedVotes(voter);
- }
- }
- contract ColorBonds is ColorToken{
- string constant public name = "Prism";
- string constant public symbol = "Aura";
- uint8 constant public decimals = 12;
- constructor(address _asset) public ColorToken(_asset){}
- }
- abstract contract PyramidContract{
- function sellBonds(uint amount) public virtual returns(uint returned_eth, uint returned_resolves, uint initialInput_ETH);
- function resolveToken() public virtual returns(ERC20);
- function pullResolves(uint amount) public virtual returns(uint);
- function reinvestEarnings(uint amountFromEarnings) public virtual returns(uint,uint);
- function withdraw(uint amount) public virtual returns(uint);
- function fund() payable public virtual returns(uint);
- function resolveEarnings(address _owner) public view virtual returns (uint256 amount);
- }
- library Common {
- //assemble the given address bytecode. If bytecode exists then the _addr is a contract.
- function isContract(address _addr) public view returns (bool is_contract) {
- uint length;
- assembly {
- //retrieve the size of the code on target address, this needs assembly
- length := extcodesize(_addr)
- }
- if(length>0) {
- return true;
- }else {
- return false;
- }
- }
- }
- abstract contract ERC223ReceivingContract{
- function tokenFallback(address _from, uint _value, bytes calldata _data) external virtual;
- }
Advertisement
Add Comment
Please, Sign In to add comment