OnlyPwner-ALL OR NOTHING-WriteUp

OnlyPwner-ALL OR NOTHING-WriteUp

OnlyPwner-ALL OR NOTHING-WriteUp-魔法少女雪殇
OnlyPwner-ALL OR NOTHING-WriteUp
此内容为付费阅读,请付费后查看
10
立即购买
您当前未登录!建议登陆后购买,可保存购买订单
付费阅读

ALL OR NOTHING

先看一下部署合约

pragma solidity 0.8.20;

import {AllOrNothing} from "../src/AllOrNothing.sol";
import {Script} from "forge-std/Script.sol";
import {console} from "forge-std/console.sol";

contract Deploy is Script {
    function run() external {
        vm.startBroadcast();

        address user = vm.envAddress("USER");
        AllOrNothing allOrNothing = new AllOrNothing(1 ether, 10 minutes);

        allOrNothing.bet{value: 1 ether}(1, address(uint160(user) + 1));
        allOrNothing.bet{value: 1 ether}(1, address(uint160(user) + 2));
        allOrNothing.bet{value: 1 ether}(1, address(uint160(user) + 3));
        allOrNothing.bet{value: 1 ether}(1, address(uint160(user) + 4));
        allOrNothing.bet{value: 1 ether}(1, address(uint160(user) + 5));

        payable(user).transfer(1 ether);

        console.log("address:AllOrNothing", address(allOrNothing));
    }
}

从部署来看,首先初始化阶段给了1eth,然后调用bet,也就是五个用户每个用户都给合约了1eth,然后最后用transfer给用户合约1eth。所以合约应该是有5个eth。

看一下满足条件合约

图片[10]-OnlyPwner 区块链自用Write UP(更新至LIQUID STAKING)-魔法少女雪殇

简单粗暴的让合约的钱为空,那么接下来我们看一下合约本体。

pragma solidity 0.8.20;

import {IAllOrNothing} from "./interfaces/IAllOrNothing.sol";
import {Multicall} from "./Multicall.sol";

/// A contract where users can bet on a random number being published.
/// The user who is closest to the number wins all the bets.
contract AllOrNothing is IAllOrNothing, Multicall {
    address public owner;
    address public bestPlayer;
    uint256 public winningNumber;
    mapping(address => uint256) public bets;

    uint256 public immutable BET_AMOUNT;
    uint256 public immutable DEADLINE;
    uint256 public immutable DECLARE_DEADLINE;

    constructor(uint256 betAmount, uint256 duration) {
        owner = msg.sender;
        BET_AMOUNT = betAmount;
        DEADLINE = block.timestamp + duration;
        DECLARE_DEADLINE = DEADLINE + 1 days;
    }

    function declareWinner(address user) external {
        require(bets[user] != 0, "Must have placed bet");
        require(
            block.timestamp >= DEADLINE && block.timestamp < DECLARE_DEADLINE,
            "Deadline not passed"
        );
        require(winningNumber != 0, "Winning number not published");

        if (bestPlayer == address(0)) {
            bestPlayer = user;
            return;
        }

        unchecked {
            uint256 distance = bets[user] > winningNumber
                ? bets[user] - winningNumber
                : winningNumber - bets[user];

            uint256 bestDistance = bets[bestPlayer] > winningNumber
                ? bets[bestPlayer] - winningNumber
                : winningNumber - bets[bestPlayer];

            if (distance < bestDistance) {
                bestPlayer = user;
            }
        }
    }

    function withdrawWinnings() external {
        require(msg.sender == bestPlayer, "Must be best player");
        require(block.timestamp >= DECLARE_DEADLINE, "Deadline not passed");

        payable(msg.sender).transfer(address(this).balance);
    }

    function bet(uint256 number, address recipient) external payable {
        require(bets[recipient] == 0, "Already placed bet");
        require(msg.value == BET_AMOUNT, "Value too low");
        require(block.timestamp < DEADLINE, "Deadline passed");

        bets[recipient] = number;
    }

    function void() external {
        require(bets[msg.sender] != 0, "Must have placed bet");
        require(block.timestamp < DEADLINE, "Deadline passed");

        bets[msg.sender] = 0;
        payable(msg.sender).transfer(BET_AMOUNT);
    }

    function transfer(address to) external {
        require(bets[msg.sender] != 0, "Must have placed bet");
        require(bets[to] == 0, "Recipient must not have placed bet");

        bets[to] = bets[msg.sender];
        bets[msg.sender] = 0;
    }

    function publish(uint256 number) external {
        require(msg.sender == owner, "Must be owner");
        require(block.timestamp >= DEADLINE, "Deadline not passed");

        winningNumber = number;
    }
}

© 版权声明
THE END
喜欢就支持一下吧
点赞15 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情

    暂无评论内容