Back Home


Good Websites

  • Solidity docs

  • Good articles:


    This just launched:

    About to dive in, but seems like a big deal!


    Another interesting thing I found:

    Building Pristine - a Bitcoin backed stablecoin


    Pristine is a protocol that allows users to deposit Bitcoin and borrow a stablecoin (called Satoshi), against the deposited Bitcoin. For a more detailed description of the protocol, see the github repo.

    Things to consider

    What happens after a user opens and closes a position? Is the users position deleted from storage? - Currently every address can only open a position once, after that, they can only alter that position, either by depositing, withdrawing, borrowing or repaying.

    How do liquidations work? - No fancy auctions, when a users position is between 110% and 100% collateralizes, anyone can pay all their debt and receive their collateral.

    Main functions

    Open Position
    function open(uint256 _amount) public returns (uint256) {
        if (UserPosition[msg.sender] != 0)
            revert CannotCreateMultiplePositions();
        WBTC.transferFrom(msg.sender, address(this), _amount);
        Positions[positionCounter] = Position(
        UserPosition[msg.sender] = positionCounter;
        emit Opened(positionCounter, msg.sender, _amount);
        return positionCounter; 
    Deposit Bitcoin
    function deposit(uint256 _amount, uint256 _id) public PositionExists(_id) {
        WBTC.transferFrom(msg.sender, address(this), _amount);
        Positions[_id].collatAmount += _amount;
        emit Deposited(_id, _amount);
    function withdraw(uint256 _amount, uint256 _id) public PositionExists(_id) {
        WBTC.transfer(msg.sender, _amount);
        Positions[_id].collatAmount -= _amount;
        if (!checkPositionHealth(_id)) revert PositionNotHealthy(_id);
        emit Withdrew(_id, _amount);
    Borrow Satoshi
    function borrow(uint256 _amount, uint256 _id) public PositionExists(_id) {, _amount);
        Positions[_id].borrowedAmount += _amount;
        if (!checkPositionHealth(_id)) revert PositionNotHealthy(_id);
        emit Borrowed(_id, _amount);
    Repay Sathoshi
    function repay(uint256 _amount, uint256 _id) public PositionExists(_id) {
        Satoshi.burn(msg.sender, _amount);
        Positions[_id].borrowedAmount -= _amount;
        emit Repayed(_id, _amount);
    Liquidate Position
    function liquidatePosition(uint256 _id) public PositionExists(_id) {
        if (checkPositionHealth(_id)) revert PositionHealthy(_id);
        Position memory position = Positions[_id];
        Satoshi.burn(msg.sender, position.borrowedAmount);
        WBTC.transfer(msg.sender, position.collatAmount);
        //Update Positions
        delete Positions[_id];
        delete UserPosition[position.owner];
        emit Liquidated(_id, position.collatAmount);
    Redeem Position
    function redeem(uint256 _id, uint256 _amount) public PositionExists(_id) {
        Satoshi.burn(msg.sender, _amount);
        uint256 btcPrice = getCollatPrice();
        uint256 redemptionRate = getRedemptionRate(_id); // Get the redemption rate based on the collateral ratio
        uint256 redeemableBTC = (((_amount * redemptionRate) / 10 ** 12) / btcPrice);
        // Ensure the position has enough collateral for the redemption
        Position memory position = Positions[_id];
        if (position.collatAmount < redeemableBTC) revert NotEnoughCollateral();
        if (position.borrowedAmount < _amount) revert NotEnoughDebt();
        position.collatAmount -= redeemableBTC;
        position.borrowedAmount -= _amount;
        Positions[_id] = position;
        WBTC.transfer(msg.sender, redeemableBTC);
        emit Redeemed(_id, msg.sender, _amount);