I was assigned to write a smart contract for class (to be deployed on a test-net), which, upon receiving ETH, returns to the sender some amount of tokens with symbol "Thanks". I want this contract to disperse dT tokens for an infinitesimal amount dm dollars according to


where m is the total value in USD the contract has received so far.

This is basically just a "GoFundMe" contract with the property that as I receive more USD, the amount of "Thanks" sent per USD received decreases. (I.e., the more broke I am, the more I thank you for giving me money.) I'm using Chainlink price oracle to keep track of the current ETH/USD price, and I've already finished the assignment, if you were wondering.

Now, this got me thinking about how the value of a "Thanks" changes depending on how I implement this process.

The basic functionality (skipping irrelevant parts of the contract) I have coded includes a mapping balanceOf to keep track of balances, a function _mint to mint (dT) tokens to an address (msg.sender), and a receive function, which activates whenever the contract receives a donation:

receive() external payable onlyExternal {
   require(msg.value > 0, "ETH value must be greater than 0.");

   uint256 dm = _ETHtoUSD(msg.value);
   uint256 m = totalValueUSD;
   uint256 dT = dm / sqrt(m + 1);

   _mint(msg.sender, dT);

   totalValueUSD += dm;

The modifier onlyExternal makes sure another contract isn't sending me ETH (for security reasons, so I'm told), the function _ETHtoUSD uses the price oracle to convert the sent ETH to USD, and totalValueUSD and totalSupply keep track of the total amount of USD the contract has received and the total amount of "Thanks" I've minted. (I'm not entirely certain how we justify the code as being morally the same as the equation dT=dm/(m+1)^{1/2} with infinitesimals, but let's ignore this.)

What's being done here is that, initially, there are no "Thanks" tokens minted. Every time someone donates, we mint more "Thanks" according to our rule, and give those tokens to the donator.

Another way to do this is as follows: Say I have a funding target of 1,000,000 USD within, say, the next month. I can calculate how many "Thanks" tokens I'm likely to need to reach that funding target. I could opt to mint all those "Thanks" tokens initially and remove the option to mint more tokens in the future.

What are the benefits and drawbacks (in theory or practice) to minting a particular amount of "Thanks" tokens from the start, as opposed to my implementation, and how does the value of a "Thanks" change as we approach the funding target, in either case?

If we initially mint all the "Thanks" we expect to need, will allowing ourselves the option to mint more "Thanks" tokens at a later date dilute their value?

1 Answer 1

  1. to check if the transaction is initiated by a smart contract, you can use this: require(msg.sender == tx.origin) which makes sure no contract is calling your function.

  2. Minting a token will only result in deflationnary mechanism, meaning the token value will only decrease. but to actually have any value, the token must be paired in a pool. otherwise it has no value. The value will be dependendant on the liquidities present in the pool(s) created for this token, and the ratio of those pools. The more tokens you mint, the more people will be able to sell tokens and decrease that value.

A more sensible approach would be to create a pool for the token, mint an initial supply and give some to the contract to distribute proportionally to usd received (or not if you don't want that)

  • I already have modifier onlyExternal() { require(msg.sender == tx.origin, "Only external accounts can call this function."); _; }
    – Alex Byard
    Dec 3, 2023 at 18:00
  • I was getting confused with value in the sense of how much USD you have to pay to get a "thanks" and value in the sense of how many "thanks" are in the market.
    – Alex Byard
    Dec 3, 2023 at 18:04
  • 1
    the only way to estimate this would be to write a mathematical function representing your tokenomics
    – Yann
    Dec 4, 2023 at 14:34

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.