0
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Fomo3D {
    enum State {
        INACTIVE,
        ACTIVE
    }
    State public currentState = State.INACTIVE;
    address payable public king;
    uint public start;
    uint public end;
    uint public hardEnd;
    uint public pot;
    uint public houseFee = 2;
    uint public initialKeyPrice;
    uint public totalKeys;
    address payable[] public keyHolders;
    mapping(address => uint) public keys;

function kickStart() 
    external 
    inState(State.INACTIVE) {
    currentState = State.ACTIVE;
    _createRound();
}

function bet() 
    external 
    payable 
    inState(State.ACTIVE) {
    if(block.timestamp > hardEnd) {
        payable(msg.sender).transfer(msg.value);
        _distribute();
        _createRound();
        currentState = State.INACTIVE;
        return;
    }
    
    //Keys
    uint keyCount = msg.value / getKeyPrice();
    keys[msg.sender] += keyCount;
    totalKeys += keyCount;
    bool alreadyAdded = false;
    for(uint i = 0; i < keyHolders.length; i++) {
        if(keyHolders[i] == msg.sender) {
            alreadyAdded = true;
        }
    }
    if(alreadyAdded == false) {
        keyHolders.push(payable(msg.sender));
    }
    
    //Other
    pot += msg.value;
    end = end + 30 > hardEnd ? hardEnd : end + 30;
}

function getKeyPrice() view public returns(uint) {
    uint periodCount = (block.timestamp - start) / 30;
    return initialKeyPrice + periodCount * 0.01 ether;
}

function _distribute() internal {
    uint netPot = pot * (100 - houseFee) / 100;
    uint lastIndex = keyHolders.length - 1;
    king = keyHolders[lastIndex];
    king.transfer((netPot * 50) / 100); 
    for(uint i = 0; i < keyHolders.length; i++) {
        address payable keyHolder = keyHolders[i];
        if(keyHolder != keyHolders[lastIndex]) {
            (keyHolder).transfer(((netPot * 50) / 100) * (keys[keyHolder] / totalKeys));
        }
    }
}

function getStamp() public view returns(uint){
    return block.timestamp;
}
    
function _createRound() internal  {
    for(uint i = 0; i < keyHolders.length; i++) {
        delete keys[keyHolders[i]];
    }
    delete keyHolders;
    totalKeys = 0;
    start = block.timestamp;
    end = block.timestamp + 30;
    hardEnd = block.timestamp + 30;
    initialKeyPrice = 1 ether;
}

modifier inState(State state) {
    require(currentState == state, 'not possible in current state');
    _;
}

}

4
  • It would be helpful if you had a little more explanation of your code
    – sola24
    Jul 2, 2022 at 13:51
  • It's a gambling smart contract. We have players who bet the money. It works per round. During the round players will invest ether into a smart contract. In exchange of their investment, they receive some keys. The more you invest the more keys you have.Every time someone invests, it kicks off an internal timer. When this timer runs out, the last person who invested into this contract(king), win the round and get 50% of all the investment of all the players. The rest will be shares across the other palyers depending on the number of keys that they hold. Each round, has a limted timer.
    – ETH guy
    Jul 2, 2022 at 14:01
  • When you invest it, you delay the timer by 30 seconds and some point you won't be able to delay the timer and the round will end(hardEnd). It lasts 1 days and when you invest you delay it by 30 seconds.
    – ETH guy
    Jul 2, 2022 at 14:03
  • If you'd like people to help you can provide more details and share what actually happens when the round is over and how you tested it. Note that to check if the round is over you're checking hardEnd, but you only update end after betting. Jul 3, 2022 at 8:22

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.