- t: Time period (can be discrete, e.g., days, weeks, or continuous)
- u: Index for user, u = 1, 2, ..., N, where N is the number of users
- V(t): Total value of assets deposited in the underlying ERC-4626 Vault at time t
- D_u(t): Deposit amount of user u at time t. We assume deposits are cumulative, so D_u(t) represents the total deposited amount by user u up to time t
- S_u(t): Vault Shares (ERC-4626 tokens) held by user u at time t
- Y_R(t): Yield Rate of the underlying ERC-4626 Vault during time period t. This can be expressed as a percentage or a factor
- Y(t): Total yield generated by the ERC-4626 Vault during time period t
- P_R: Prize Rate – the percentage of the total yield allocated to the prize pool
- P(t): Prize Pool size for the prize draw at time t
- W: Number of winners selected in each prize draw
- Prize_i: Value of the i-th prize in a prize draw, where i = 1, 2, ..., W. Prizes can be tiered
- ∑Prize = ∑_{i=1}^{W} Prize_i: Total value of prizes distributed in a single draw
- Prob_u(t): Probability of user u winning any prize in a draw at time t
- Prob_u,i(t): Probability of user u winning the i-th prize in a draw at time t
- EV_u(t): Expected Value of prizes for user u in a draw at time t
The total value of assets in the vault at time t is the sum of all user deposits (after accounting for yield generation and potential exchange rate changes within the ERC-4626 vault). However, for simplicity in prize calculation based on shares, we often work with shares as the representation of deposit size within the Prize Vault logic. Assuming a 1:1 initial share ratio for the Prize Vault:
and also S_u(t) is approximately proportional to D_u(t) in terms of prize probability contribution.
The total yield generated by the ERC-4626 Vault during time period t is calculated based on the total value in the vault and the yield rate:
Where V(t-1) is the vault value at the beginning of the time period t, and Y_R(t) is the yield rate for period t.
The prize pool for the draw at time t is a percentage of the generated yield:
Total Vault Shares in Prize Vault:
For tiered prizes with W winners drawn without replacement, the approximate probability of winning at least one prize:
For each individual prize Prize_i, the simplified probability:
The expected value for user u:
Using the simplified probability:
For any withdrawal at time t:
Over time period T:
# A I generated slop
import matplotlib.pyplot as plt
import numpy as np
def generate_dwl_graph(p0, q0, fee_rate, edemand, esupply):
"""
Generates a Deadweight Loss (DWL) graph similar to the provided image,
using the elasticity-based approximation for DWL calculation.
Args:
p0: Equilibrium Price without fees.
q0: Equilibrium Quantity without fees.
fee_rate: Credit card transaction fee rate (as a decimal).
edemand: Price elasticity of demand (absolute value, positive).
esupply: Price elasticity of supply (positive).
"""
# --- Calculate DWL and Price/Quantity Changes ---
# DWL calculation (same as before)
dwl = 0.5 * p0 * q0 * (fee_rate**2) * (edemand * esupply / (edemand + esupply))
# Calculate change in quantity (delta Q) using elasticity approximation
delta_q = -q0 * fee_rate * (edemand * esupply / (edemand + esupply))
qd = q0 + delta_q # Quantity demanded after the fee
# Calculate price changes for consumers (Pc) and producers (Pp)
delta_pc = fee_rate * p0 * (esupply / (edemand + esupply))
delta_pp = -fee_rate * p0 * (edemand / (edemand + esupply))
pc = p0 + delta_pc # Price consumers pay
pp = p0 + delta_pp # Price producers receive
qs = q0 + (delta_pp/p0) * esupply *q0 #Simplified for demonstration. More accurate Qs is complex.
# --- Create the Plot ---
plt.figure(figsize=(8, 6)) # Adjust figure size as needed
# Demand Curve (Original)
q_values_demand = np.array([0, q0 * 1.5]) # Extend beyond equilibrium for visualization
p_values_demand = p0 - (q_values_demand - q0) * (p0 / (edemand * q0)) # Linear approx.
plt.plot(q_values_demand, p_values_demand, label='Demand', color='green')
# Supply Curve (Original)
q_values_supply = np.array([0, q0 * 1.5]) # Extend for visualization
p_values_supply = p0 + (q_values_supply - q0) * (p0 / (esupply * q0)) # Linear approx.
plt.plot(q_values_supply, p_values_supply, label='Supply', color='blue')
# 2. Points and Labels (A, B, C, D, P1, P2, Q1, Qd, Qs)
# Point A (Original Equilibrium)
plt.plot(q0, p0, 'ko') # 'ko' = black circle
plt.text(q0 + 0.02*q0, p0 - 0.03*p0, 'A', fontsize=12)
# Point B (New Consumer Price Intersection)
plt.plot(qd, pc, 'ko')
plt.text(qd + 0.02*q0 , pc + 0.02*p0, 'B', fontsize=12)
# Point C (New Producer Price Intersection)
plt.plot(qd, pp, 'ko')
plt.text(qd - 0.1*q0, pp - 0.03*p0, 'C', fontsize=12)
# Point D: Intersection of supply and new price
plt.plot(qs, pc, 'ko') # Intersection of the original supply and new consumer price.
plt.text(qs+0.02*q0, pc+0.01*p0, 'D', fontsize=12)
# Horizontal dashed lines for P1 and P2
plt.hlines(y=p0, xmin=0, xmax=q0, linestyles='dashed', color='black')
plt.hlines(y=pc, xmin=0, xmax=qs, linestyles='dashed', color='black')
plt.hlines(y=pp, xmin=0, xmax=qd, linestyles='dashed', color='black')
# Vertical dashed lines for Q1, Qd, and Qs
plt.vlines(x=q0, ymin=0, ymax=p0, linestyles='dashed', color='black')
plt.vlines(x=qd, ymin=0, ymax=pc, linestyles='dashed', color='black')
plt.vlines(x=qs, ymin=0, ymax=pc, linestyles='dashed', color='black')
# Label axes, prices and quantities
plt.text(-0.07*q0, p0, r'$P_1$', fontsize=12) #using Latex
plt.text(-0.07*q0, pc, r'$P_2$', fontsize=12)
plt.text(q0, -0.07*p0, r'$Q_1$', fontsize=12)
plt.text(qd, -0.07*p0, r'$Q_d$', fontsize=12)
plt.text(qs, -0.07*p0, r'$Q_s$', fontsize=12)
# 3. Shaded DWL Triangle
# Fill the triangle ABC
plt.fill_between([qd, q0], [pc, p0], [pp, p0], color='red', alpha=0.5)
# 4. Axis Labels and Title
plt.xlabel('Q')
plt.ylabel('P')
plt.title('Deadweight Loss from Credit Card Fees')
plt.legend(handles=[plt.Line2D([], [], color='green', label='D'),
plt.Line2D([], [], color='blue', label='S')],
loc='upper left', frameon=False)
plt.text(0.1*q0,0.95*p_values_demand[0], r'$D_L$', color='green')
plt.text(0.1*q0,0.1*p_values_supply[0], r'$S_L$', color='blue')
plt.xlim(0, q0 * 1.3) # Extend x-axis slightly
plt.ylim(0, p_values_demand[0] * 1.1) # Extend y-axis to accommodate labels
plt.tight_layout() # Prevents overlapping
plt.show()
def main():
# Example parameters (you can change these)
p0 = 100 # Equilibrium price
q0 = 1000 # Equilibrium quantity
fee_rate = 0.03 # 3% fee
edemand = 0.8 # Absolute value of demand elasticity
esupply = 1.2 # Supply elasticity
generate_dwl_graph(p0, q0, fee_rate, edemand, esupply)
if __name__ == "__main__":
main()