Good articles:
https://jtriley.substack.com/p/ethereum-virtual-machine-language
This just launched: https://github.com/pcaversaccio/createx/discussions
About to dive in, but seems like a big deal!
Another interesting thing I found: https://jtriley.substack.com/p/the-edge-programming-language?r=1qyfrf&utm_campaign=post&utm_medium=web
Summary
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.
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 Positionfunction open(uint256 _amount) public returns (uint256) {
if (UserPosition[msg.sender] != 0)
revert CannotCreateMultiplePositions();
WBTC.transferFrom(msg.sender, address(this), _amount);
positionCounter++;
Positions[positionCounter] = Position(
msg.sender,
positionCounter,
_amount,
0
);
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);
}
Withdraw
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) {
Satoshi.mint(msg.sender, _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);
}