Inspired by this Tweet - Using Chat GPT to create a SmartPy contract:
https://twitter.com/jordan_tezos/status/1637127362222469125
I was thinking myself lets try it out. I used Chat GPT-4 for this little experiment.
Obviously this should not be trusted, I would like to see the opinion of experiences SmartPy developers what they think about this code. Is it worthless? Or can you work with that and adapt some changes? I am no smart contract dev so it looks good for me but what do I know!
My Input to Chat GPT-4 was:
You are an AI smart contract programming assistant.
Follow the users requirements carefully and to the letter!
- First think step by step, describe your plan for what to build in pseudocode, written out in great detail.
- Then output the code in a single codeblock.
- Minimize any other prose
- Write in the Tezos Smart contract language SmartPy
Requirements:
Here I put an explanation what rebase tokens on ethereum are with some examples.
Based on this create a similar smart contract with functions of a rebase token but on Tezos in SmartPy.
The rebases shall take place every 24 hours and occur if the price of the token will differ from the USD price by 5%. You will probably need to call an oracle to check the USD price for that.
This was the response:
-
Import necessary SmartPy libraries
-
Initialize contract storage
- target_price
- rebase_period
- last_rebase_timestamp
- total_supply
- balances (map of address to balance)
- price_oracle (oracle contract address)
-
Implement a rebase function
- Check if 24 hours have passed since the last rebase
- Call the price oracle to get the current token price in USD
- Calculate the percentage difference between the target price and the current price
- If the percentage difference is greater than or equal to 5%, perform the rebase
- Calculate the new total supply
- Update balances proportionally for all token holders
- Update the last rebase timestamp
- Implement entry points for standard token functionality (transfer, approve, allowance, etc.)
And here is the SmartPy code:
import smartpy as sp
class ElasticSupplyToken(sp.Contract):
def __init__(self, target_price, price_oracle):
self.init(
target_price=target_price,
rebase_period=sp.timestamp(24 * 60 * 60),
last_rebase_timestamp=sp.timestamp(0),
total_supply=sp.nat(0),
balances=sp.big_map(tkey=sp.TAddress, tvalue=sp.TNat),
price_oracle=price_oracle,
allowances=sp.big_map(tkey=(sp.TAddress, sp.TAddress), tvalue=sp.TNat),
)
@sp.entry_point
def rebase(self, params):
sp.verify(
sp.now - self.data.last_rebase_timestamp >= self.data.rebase_period,
message="Not enough time has passed since the last rebase",
)
current_price = sp.contract(
sp.TMutez, self.data.price_oracle, "get_token_price"
).open_some()
sp.transfer(sp.unit, sp.mutez(0), current_price)
price = sp.local("price", sp.fst(sp.result()))
sp.verify(price > 0, message="Invalid price")
percentage_difference = (
sp.abs(self.data.target_price - price) * 100) / self.data.target_price
sp.verify(
percentage_difference >= 5, message="Price difference is less than 5%"
)
new_total_supply = (self.data.total_supply * price) // self.data.target_price
factor = new_total_supply * sp.nat(10_000) // self.data.total_supply
for addr in self.data.balances.keys():
self.data.balances[addr] = (self.data.balances[addr] * factor) // sp.nat(10_000)
self.data.total_supply = new_total_supply
self.data.last_rebase_timestamp = sp.now
@sp.entry_point
def transfer(self, params):
sp.verify(
self.data.balances[sp.sender] >= params.value,
message="Insufficient balance",
)
self.data.balances[sp.sender] -= params.value
self.data.balances[params.to] += params.value
@sp.entry_point
def approve(self, params):
self.data.allowances[(sp.sender, params.spender)] = params.value
@sp.entry_point
def transfer_from(self, params):
sp.verify(
self.data.allowances[(params.from_, sp.sender)] >= params.value,
message="Insufficient allowance",
)
sp.verify(
self.data.balances[params.from_] >= params.value,
message="Insufficient balance",
)
self.data.allowances[(params.from_, sp.sender)] -= params.value
self.data.balances[params.from_] -= params.value
self.data.balances[params.to] += params.value
# Instantiate the contract and compile it to Michelson
target_price = 1_000_000 # 1 USD in micro-USD
price_oracle = sp.address("tz1...") # Address of the price oracle contract
elastic_token = ElasticSupplyToken(target_price, price_oracle)
sp.add_compilation_target("elastic_token", elastic_token)