1 de diciembre de 2021
UMA es una plataforma que permite a los usuarios ingresar contratos financieros de confianza minimizada en la cadena de bloques Ethereum. Previamente auditamos el oráculo descentralizado, una plantilla de contrato financiero particular, algunas solicitudes de extracción ad hoc, la plantilla Multipartidista Perpetuo y varias solicitudes de extracción incrementales durante un compromiso más largo. En esta auditoría, revisamos un nuevo mecanismo para enviar tokens rápidamente desde una cadena de capa 2 a la red principal de Ethereum y los cambios relacionados con Optimistic Oracle. La revisión fue completada por 2 auditores durante 3 semanas.
Lo que hacemos
El compromiso auditado es f24ad501c8e813cf685f72217e7f13c8f3c366df
y el alcance incluye los siguientes contratos:
- contratos/puente-asegurado/* (excepto contratos de prueba)
- contratos-ovm/puente-asegurado/implementacion/*
- contratos/común/implementación/AncillaryData.sol
- contratos/oracle/implementación/SkinnyOptimisticOracle.sol
También revisamos los cambios en los archivos de solidez en Solicitud de extracción 3445.
Se asumió que todo el código externo y las dependencias del contrato funcionaban según lo documentado.
Resumen del sistema
Las cadenas compatibles de capa 2 (L2), Optimism y Arbitrum, proporcionan un mecanismo para transferir fondos a la red principal de Ethereum (L1). Sin embargo, por razones de seguridad, hay un retraso significativo antes de que finalicen esas transferencias. Para abordar esto, los titulares de tokens L2 pueden depositar fondos en un contrato UMA, la Caja de depósito, sabiendo que los tokens eventualmente se transferirán (como un lote) a un contrato UMA L1, el Bridge Pool. Hay un Bridge Pool separado para cada token que se va a transferir.
Luego de un depósito L2, cualquiera puede transmitir los detalles al L1 Bridge Pool, que espera un breve período en caso de que alguien quiera cuestionar la información transmitida. Todas las disputas son manejadas por Skinny Optimistic Oracle (descrito a continuación). Antes de aceptar el relevo, los proveedores de liquidez deben financiar previamente el contrato de Bridge Pool a cambio de tokens LP. Las retransmisiones indiscutibles se suponen válidas y Bridge Pool completa la transferencia utilizando sus propias reservas, donde una fracción de la transferencia se desvía al retransmisor y una fracción se retiene como tarifas de liquidez. Los fondos eventualmente se repondrán cuando se finalice el depósito L2 y las tarifas de liquidez se asignen a los titulares de tokens LP.
Bridge Pool también permite que cualquiera financie individualmente una transferencia (sin las reservas de Bridge Pool) antes de que expire el período de disputa, a cambio de una fracción del monto de la transferencia. Dado que el relevo aún se puede disputar, estos fondos se perderían si se considerara que el relevo es incorrecto. Se espera que, en la mayoría de los casos, este mecanismo permita a los usuarios experimentar transferencias de tokens L2 a L1 inmediatas.
El Skinny Optimistic Oracle es conceptualmente muy similar al Optimistic Oracle existente. Proporciona un mecanismo de incentivo para que los usuarios simplemente afirmen el resultado de una solicitud de Oracle, que se supone que es precisa si no se cuestiona. Las disputas se relegan al mecanismo DVM más lento descrito en nuestros informes de auditoría anteriores. La principal diferencia es que la nueva versión requiere que los usuarios proporcionen toda la información relevante al ejecutar llamadas a funciones, por lo que no es necesario guardar o recuperar los valores del almacenamiento. También elimina la posibilidad de que los solicitantes cambien los parámetros de configuración en las solicitudes activas.
Hemos revisado previamente el contrato Long-Short-Pair, que proporciona un mecanismo genérico para crear varios instrumentos financieros. Estos contratos pueden resolverse cuando se llega a su vencimiento y se conoce el precio de liquidación. Los cambios introducidos por el Pull Request 3445 introducen la posibilidad de resolver los contratos anticipadamente si se conoce el precio de liquidación antes del tiempo de vencimiento.
Roles privilegiados
Las cajas de depósito L2 tienen varios parámetros de configuración, incluidos los tokens admitidos y la tasa máxima para enviar tokens por lotes a través del puente a L1. También deben configurarse para garantizar la coherencia entre el contrato de token L1, el contrato de token L2 y el Bridge Pool correspondiente. Estos parámetros los establece un contrato de administrador en L1, que también parametriza el proceso de resolución de disputas de los grupos puente. Se espera que el contrato sea controlado por el mecanismo de gobierno de UMA, por lo que los usuarios deben confiar en este proceso para administrar el sistema de manera sensata y justa.
Dependencias del ecosistema
Todos los componentes revisados utilizan una lógica basada en el tiempo, lo que significa que dependen de la disponibilidad de Ethereum. En particular, si las transacciones de disputa se retrasan significativamente, las retransmisiones o propuestas de precios no válidas pueden confirmarse incorrectamente.
Además, el token bridge asume implícitamente que todos los fondos enviados a las cajas de depósito L2 eventualmente se transferirán al pool puente L1 correspondiente. Esto se basa en el funcionamiento correcto y continuo de los puentes Optimism y Arbitrum, y sus mecanismos de resolución de disputas.
Por último, los tokens enviados a la caja de depósito L2 se asignan al grupo puente en L1, no al destinatario previsto. Para recuperar los fondos del grupo, los poseedores de tokens L1 primero deben combinarlos con tokens adicionales. Por lo tanto, el mecanismo se basa en un mercado suficientemente profundo de tokens L1 para garantizar que siempre haya liquidez.
Problemas informados por el cliente
Durante la auditoría, el equipo de UMA identificó de forma independiente una serie de problemas y comportamientos que vale la pena destacar:
Si los parámetros Optimistic Oracle o Bridge Admin cambian durante el período de desafío de un relevo, la disputa del relevo elimina el relevo sin recurso adicional para el proponente o el disputador. Por ejemplo, imagine que el relé se envía para el token colateral
TOKEN_A
, pero en medio del relevoTOKEN_A
se elimina de la lista blanca de garantías. Una disputa ahora se revertirá ya que no puede enviar ninguna solicitud de precio al OO o DVM para garantías no incluidas en la lista blanca. Dado que no queremos bloquear las solicitudes de disputa válidas, elBridgePool
eliminará el relé pendiente paraTOKEN_A
en el caso de una disputa. Las consecuencias de esta decisión de diseño son:
1. Un aumento en la tarifa final hará que: Cualquier retransmisión pendiente en ese token sea "cancelable" mediante disputa, ya sea correcta o incorrecta. Una cancelación no beneficia a ninguna de las partes, por lo que supone la existencia de disputadores honestos que están dispuestos a eliminar la (rara) mala solicitud que ocurre durante la ejecución de un cambio de tarifa final. Esto también significa que es posible que un afligido gaste gasolina para cancelar los relevos y obligarlos a volver a retransmitirlos.
2. Una eliminación de la lista blanca del identificador o token, lo que no debería suceder a menos que algo salga muy mal, causaría:
3. Un período prolongado de solicitudes indiscutibles donde cualquier solicitud puede cancelarse y no existen incentivos económicos para disputar. Esto parece mejor que la alternativa de bloquear las disputas por completo, pero ciertamente es bastante malo, ya que cualquier agraviado puede bloquear relevos indefinidamente pagando gasolina o enviar relevos malos sin castigo (aparte de las tarifas de gas).Nota: esta es una alternativa a tener el OO que "congela" parámetros como la tarifa final o la lista blanca de garantías durante algún tiempo, pero esto requeriría llamadas adicionales al OO, lo que sería costoso para el camino feliz.
Los relés se pueden acelerar mediante
speedUpRelay()
después de que pasan vivacidad. Si bien no vemos ningún riesgo con esto, abre la posibilidad de préstamos rápidos + aceleraciones + liquidación después de la vida, dando al prestatario rápido la tarifa de retransmisión instantánea de forma "gratis". Prevenimos esto en esta propuesta PR.
On
settle
, Si elBridgePool
es unWETH
pool y el destinatario es un contrato que no espayable
(no puede aceptar ETH), entoncessettle
fallará. Planeamos arreglar esto y recurrir al envíoWETH
, pero aún no se ha realizado ningún trabajo destacado al respecto.
In
relayDeposit
, comprobamos que elBridgePool
El saldo de es mayor que la cantidad a transmitir MÁS el bono del proponente. Esta es una verificación desactualizada y demasiado conservadora ya que el vínculo del proponente se extrae del usuario después de la verificación. Abordamos esto en esta propuesta PR.
Acabo de detectar un error donde
chainId
inBridgePool
, incluido como parte delDeposit
estructura y como entrada de función a todas las funciones relacionadas con el relé (es decir,relayDeposit
,speedUpRelay
,settle
) es tipouint8
. Este es un tipo demasiado pequeño para manejar Arbitrum, por ejemplo, cuyo ID es 421611. De hecho, detectamos este error y lo solucionamos en el lado L2:BridgeDeposit
ha fijado suchainId
escribir auint256
. Este PR hará que elchainId
onBridgePool
coincidir con el tipo enBridgeDepositBox
: Protocolo UMA/protocolo#3463
Anteriormente, la función de disputa no restaba el monto del depósito de
pendingReserves
(esta es la variable que rastrea cuánto del fondo de reserva está bloqueado debido a relevos que aún no se han liquidado). El resultado fue que cada disputa bloquearía indefinidamente el monto del relevo en el grupo. No puede ser retirado por LP ni utilizado por futuros repetidores. La solución está aquí: Protocolo UMA/protocolo#3473.
Encontramos un error en
BridgeDepositBox
dondehasEnoughTimeElapsedToBridge
no comprueba si unuint256
el valor es igual a0
por defecto: Fijado en PR 3484
El método de tipo de cambio (que modifica el estado) se llama entre los tokens que se transfieren y los tokens LP que se acuñan en el método addLiquidity del contrato del grupo puente. Este cálculo debe trasladarse a la parte superior del método. Esto provoca valores de estado muy extraños. Ver relaciones públicas esta página arreglar.
El método de la vista
liquidityUtilizationPostRelay
(que solo se usa fuera de la cadena), informa un número de utilización incorrecto. el denominador en esta línea no debería ser sololiquidReserves
, debería ser una representación de las reservas utilizadas y no utilizadas. Reparado esta página.
Actualizar
Además de las correcciones de problemas, también revisamos los siguientes cambios incrementales:
- PR3500 elimina el parámetro de token redundante de
BridgePool
eventos. - PR3478 agrega la tarifa final de DVM a la lista de variables almacenadas en caché localmente.
- PR3460 tiene en cuenta un posible caso marginal de utilización de liquidez negativa (además de abordar N04)
- PR3482 elimina archivos redundantes y actualiza las constantes de OVM de acuerdo con los cambios de OVM 2.0.
- PR3585 actualiza el
BridgeDepositBox
interfaz para la coherencia y utiliza el OpenZeppelinSafeERC20
biblioteca.
Mientras revisábamos las correcciones, identificamos otro problema. Al determinar el valor de BridgePool
tokens LP, hay un cálculo intermedio que podría inesperadamente desbordamiento negativo, que deshabilitaría temporalmente la adición y eliminación de liquidez. Se debe reordenar el cálculo para sumar las reservas utilizadas antes de restar las cuotas no distribuidas.
Severidad crítica
[C01] Recompensa de proponente atrapado
El LongShortPair
contrato recupera una recompensa de proponente desde cualquier dirección que active el vencimiento, que se utiliza para incentivar las propuestas de precios en Optimistic Oracle. sin embargo, el LongShortPairCreator
contrato también recupera y reenvía los fondos de la dirección del implementador. Estos fondos adicionales no se transfieren al Optimistic Oracle y, en cambio, permanecen atrapados dentro del LongShortPair
contrato.
Considere eliminar la transferencia duplicada.
Actualizar: Corregido a partir de la confirmación 9bab1ff353a417952ba8c96a098773f340d9da17
in PR3523.
Alta severidad
[H01] Los relés simultáneos agotan las reservas
El relayDeposit
función de la BridgePool
contrato asegura que el contrato tiene fondos suficientes para ejecutar la transferencia. Sin embargo, no da cuenta de las reservas pendientes, que realiza un seguimiento de los fondos destinados a relevos activos. Por lo tanto, varios relevos simultáneos pueden depender de los mismos fondos y es posible que no todos se liquiden de inmediato. En particular, con un flujo constante de transferencias, las devoluciones de repetidores instantáneos pueden retrasarse indefinidamente.
Considere prevenir relevos que causarían que las reservas pendientes excedan las reservas líquidas.
Actualizar: Corregido a partir de la confirmación 6290f3facbca8d878605a1d390ed59d4b6b6db02
in PR3501.
[H02] Los límites del parámetro puente no coinciden
El deposit
función de las BridgeDepositBox
El contrato, desplegado en cadenas de capa 2, se utiliza para unir fondos entre L2 y L1. En particular, se incentiva a los repetidores a relé los detalles de la transacción en el L1 asociado BridgePool
. Sin embargo, la caja de depósito utiliza límites inclusivos para restringir las tarifas de retransmisión, mientras que el grupo puente utiliza límites exclusivos. Esto significa que algunos depósitos (con tarifas de retransmisión del 25 %) no se pueden retransmitir y los fondos serán inaccesibles en ambas capas.
Considere sincronizar las validaciones en ambas capas para garantizar que todos los depósitos válidos se puedan retransmitir.
Actualizar: Corregido en compromiso 2345966b3a2ace0159379b3a13256cc1a4c5d52f
of PR3494. Esto se clasificó originalmente como gravedad crítica, pero se rebajó cuando el equipo de UMA señaló que los fondos no quedarían estrictamente atrapados y podrían liberarse si los votantes de DVM aceptaban una descripción de retransmisión modificada para los depósitos afectados.
Severidad media
[M01] Devoluciones de llamada a dirección incorrecta
El SkinnyOptimisticOracle
invoca funciones de devolución de llamada en el solicitante de precios, si existen, para que el solicitante pueda responder a cambios de estado significativos. Sin embargo, la devolución de llamada se invoca incorrectamente en el proponente de precios en lugar del solicitante de precios en las proposePriceFor
función. Esto significa que el solicitante de precios no puede responder a las propuestas de precios.
Afortunadamente, esta función no se usa en el código base actual. Sin embargo, considere invocar el priceProposed
devolución de llamada al solicitante.
Actualizar: Corregido en la confirmación 7bd3faeb6f3706132f77b9ba2dce192d1a151e74
in PR3531.
[M02] Función de adición defectuosa
El appendKeyValueBytes32
función debe combinar sus entradas en un formato bytes
formación. sin embargo, el currentAncillaryData
is descartado incorrectamente.
Dado que los datos auxiliares influye en el proceso de resolución de Oracle, un valor incorrecto podría socavar los resultados del oráculo. Afortunadamente, solo hay una llamada a appendKeyValueBytes32
en el código base, y utiliza un vacío currentAncillaryData
búfer, por lo que el error no afecta este caso.
Considere actualizar el appendKeyValueBytes32
función para que el currentAncillaryData
se incluye en la matriz de bytes devuelta.
Actualizar: Corregido en compromiso 5609433c154f47e8ee9c52f9b6d7c787fbe3e455
of PR3532.
[M03] Validación de datos auxiliares incompleta
El LongShortPair
constructor confirma que el customAncillaryData
es lo suficientemente pequeña. Sin embargo, no tiene en cuenta la campo de caducidad anticipada. Esto significa el Oráculo Optimista puede rechazar inesperadamente solicitudes de precios de vencimiento anticipado, lo que deshabilitaría esta característica.
Considere actualizar la validación para tener en cuenta el campo adicional.
Actualizar: Corregido a partir de la confirmación 4a56e66492f40e20254cebb145c2d91304f7cb43
in PR3524.
[M04] Marca de tiempo cero mal manejada
En LongShortPair
contrato, una marca de tiempo de caducidad anticipada cero es usado como bandera para indicar que nadie ha activado el mecanismo de caducidad anticipada. Sin embargo, es posible activar ese mecanismo con una marca de tiempo cero. En este escenario, el Oráculo Optimista será invocado pero el protección contra solicitudes de precios posteriores no será efectivo. Afortunadamente, una vez se elige el precio de liquidación, no se anulará, por lo que esto no dará lugar a acuerdos incoherentes. No obstante, una solicitud de precio posterior podría cambiar la marca de tiempo de caducidad anticipada registrada, incluso si se utiliza la marca de tiempo cero para determinar el precio de liquidación. también podría emitir un evento engañoso.
Considere la posibilidad de evitar el vencimiento anticipado utilizando la marca de tiempo cero.
Actualizar: Corregido a partir de la confirmación 11d287c07c93c04f534b2ef3c869966d9f18ac60
in PR3526.
[M05] Posible enlace cero
El requestPrice
función de la SkinnyOptimisticOracle
contrato usa la tarifa final como bono si no se especifica la fianza. sin embargo, el requestAndProposePriceFor
función puede usar un enlace cero, lo que contradice su @notice
y @param
comentarios Un vínculo cero debilita el incentivo contra propuestas inválidas o disputas.
Afortunadamente, el solo llamar a esta funcion en el código base se establece un vínculo de proponente. Sin embargo, considere usar la tarifa final si no se especifica la fianza.
Actualizar: Corregido a partir de la confirmación daaabfc342ba1395a577159b6eb26adb20fcd232
in PR3534.
[M06] Privilegios de administrador innecesarios
El BridgePool
contrato hereda de ExpandedERC20
para que pueda emitir tokens LP a los proveedores de liquidez. Esto hereda la funcionalidad de OpenZeppelin ERC20
contrato y también proporciona privilegios de administrador al implementador de contratos, lo que les permite acuñar y quemar tokens LP. Sin embargo, esta facultad no es necesaria y, de ejercerse, podría penalizar injustamente a los proveedores de liquidez.
Considere modificar BridgePool
heredar directamente de ERC20
en lugar de ExpandedERC20
.
Actualizar: Corregido en compromiso 370e8b21b660543eadbd764fed984a5bdeddce24
in PR3492.
Gravedad baja
[L01] No se puede liquidar al vencimiento
El settle
función de la LongShortPair
contrato considera las condiciones de liquidación cuando la hora actual es estrictamente anterior o posterior a la fecha de caducidad. Sin embargo, se revierte incorrectamente cuando la hora actual coincide con la marca de tiempo de caducidad.
Considere el uso de un límite inclusivo para que coincida con el postExpiration
modificador.
Actualizar: Corregido en compromiso f03cdaa50b16d29e8f42f000bf7cd50a042cf616
in PR3527.
[L02] Mensaje de error faltante en la instrucción require
Hay una declaración de requerimiento en el BridgePool
contrato sin un mensaje de error.
Considere incluir mensajes de error específicos e informativos en todas las declaraciones requeridas.
Actualizar: Corregido a partir de la confirmación 67e60faa3a44c842c37211d2e903a983ff192e57
in PR3536.
[L03] Cadenas de documentación faltantes
Hay algunas instancias a lo largo del código base donde el Especificación natural de Ethereum falta o está incompleto. Ejemplos incluyen:
Considere documentar minuciosamente todas las funciones (y sus parámetros) que forman parte de la API pública de los contratos.
Actualizar: Los comentarios resaltados se corrigieron en la confirmación. e943e85a7dae60acd17a6d6aa027fbb1017c95ee
of PR3533. No validamos la integridad de NatSpec en el resto del código base.
Notas e información adicional
[N01] Valor de devolución de llamada no verificado
En deposit
función de la L2 BridgeDepositBox
contrato hay una llamada de bajo nivel al l2Token
cuando l1Token
is l1Weth
. Esta llamada de bajo nivel es para el deposit()
función que pertenece a la WETH interfaz. Si esto l2Token
se comporta exactamente como WETH, nunca debería fallar. Pero en el caso de la l2Token
se comporta de manera diferente y falla, no habría reversión ya que el indicador de éxito de esta llamada de bajo nivel nunca se verifica.
Considere verificar y reaccionar adecuadamente a los valores devueltos de todas las llamadas de bajo nivel.
[N02] Falta de parámetros indexados en eventos
Muchos de los eventos definidos en este código base tienen parámetros que deben indexarse:
Considerar indexación de parámetros de eventos para evitar entorpecer la tarea de búsqueda y filtrado de eventos específicos de servicios fuera de la cadena.
Actualizar: Parcialmente arreglado en commit d156b40b2ddb109806336c4d169dbdea91ed1c3e
of PR3535. chainId
parámetro de WhitelistToken
no fue actualizado
[N03] Inconsistencia de conversión implícita
El LongShortPair
contrato en general trata las marcas de tiempo como uint64
valores, que se convierten implícitamente en uint256
valores cuando pasado al Oráculo Optimista. Sin embargo, las requestTimestamp
parámetro de las _requestOraclePrice
función se convierte prematuramente en un uint256
. Esto no tiene consecuencias funcionales.
Sin embargo, en aras de la coherencia, considere el uso de un uint64
para este parámetro y permitir que se convierta implícitamente a un uint256
cuando pasa al Oráculo Optimista.
Actualizar: Corregido en compromiso 1c3c5c000ef450f5e2da056e41caff468c3fcdcb
of PR3528. La marca de tiempo ahora se emite explícitamente.
[N04] Tipo incorrecto
El sendMessage
función de la iOptimism_CrossDomainMessenger
interfaz. utiliza una uint256
límite de gas mientras que el optimismo OVM_CrossDomainEnabled
utiliza una uint32
límite de gas.
Para mantener la coherencia y la previsibilidad, considere actualizar el iOptimisim_CrossDomainMessenger
sendMessage
función para usar un uint32
limite de gases
Actualizar: Corregido a partir de la confirmación 381951aad988bbba6b2ef1b136ed5c48df50aa88
in PR3460.
[N05] Falta de validación
Todas las funciones en BridgeAdmin
esa llamada _relayMessage
suponga que el valor de la transacción coincide con el l1CallValue
parámetro, pero esto no se aplica.
Considere garantizar la correcta msg.value
se establece.
Actualizar: Corregido a partir de la confirmación f19b8d04c2343051ff2a8145abd41c39bd025063
in PR3537.
[N06] Legibilidad
El _getDepositHash
función de las BridgePool
contrato desenrolla el depositData
estructura para intersticar el l1Token
como argumento en la composición de keccak256
con el abi
codificación Esto hace que la operación sea innecesariamente detallada y puede generar errores cuando se vuelve a implementar en otras capas.
Considere simplificar los argumentos para que sean simplemente el par ordenado depositData
y l1Token
.
Actualizar: Corregido a partir de la confirmación 31754be4a818109fa12131f854c3f70d6c72dba7
in PR3538.
[N07] Función de reentrada
El requestAndProposePriceFor
función de las SkinnyOptimisticOracle
contrato hace una llamada a un no confiable msg.sender
pero no está custodiado por un nonReentrant
modificador Si bien, en este caso, esto no parece ser un problema de seguridad, puede presentar un comportamiento inesperado.
Considere agregar el nonReentrant
modificador de todas las funciones que realizan llamadas a posibles contratos que no son de confianza.
Actualizar: Corregido en compromiso b744d24e7579b7afa2c778f4dd680f26117b3990
of PR3539.
[N08] seqNum
no registrado
El relayMessage
función de las Arbitrum_Messenger
contrato no emite un evento relevante luego de ejecutar una acción sensible. los relayMessage
llamadas de función como una subrutina sentTxToL2NoAliasing
que a su vez devuelve el uint256
propuesta de seqNum
, pero este valor de retorno no se registra en el relayMessage
función.
Considere la posibilidad de emitir eventos después de que se produzcan cambios sensibles, para facilitar el seguimiento y notificar a los clientes fuera de la cadena después de la actividad del contrato.
Actualizar: Corregido a partir de la confirmación 30343f33532a6c255dc4cc18c3b497d9b2767a7c
in PR3541.
[N09] Errores tipográficos
El código base contiene los siguientes errores tipográficos:
Considere corregir estos errores tipográficos para mejorar la legibilidad del código.
Actualizar: Corregido a partir de la confirmación 2dccbe1c2c82fe2a21c179ac06c2d4f0d911a2ca
in PR3540.
[N10] Requisito de aprobación ERC20 no documentado
El requestEarlyExpiration
y expire
funciones de las LongShortPair
cada contrato asume que la persona que llama ha otorgado al contrato una asignación para tirar de la recompensa del proponente.
En aras de la previsibilidad, considere documentar este requisito en los comentarios de la función.
Actualizar: Corregido en compromiso da3754f50284480df57b90b80002da06a1ce0d02
in PR3529.
[N11] Modificador no utilizado
En BridgePool
contrato, el onlyFromOptimisticOracle
modificador está definido pero nunca se usa en el código base y, por lo tanto, debe eliminarse.
Actualizar: Corregido en compromiso 7abece6377637e8c4cd3bd07ab9adcfa051d4e94
in PR3542.
Conclusiones
Se encontraron 2 problemas críticos y 1 de alta gravedad. Se propusieron algunos cambios para seguir las mejores prácticas y reducir la superficie de ataque potencial.
- &
- 7
- Mi Cuenta
- la columna Acción
- lector activo
- Ad
- Adicionales
- dirección
- Admin
- Ventaja
- Todos
- Permitir
- abejas
- argumentos
- auditoría
- disponibilidad
- "Ser"
- MEJOR
- y las mejores prácticas
- blockchain
- Box
- PUENTE
- Error
- loco
- llamar al
- cases
- capturado
- Causar
- Reto
- el cambio
- comprobación
- código
- comentarios
- Configuración
- contiene
- contrato
- contratos
- podría
- Current
- datos
- Descentralizado
- retrasar
- Diseño
- determinar
- HIZO
- Disputa
- No
- Temprano en la
- Economic
- Southern Implants
- Eficaz
- ERC20
- ETH
- Etereum
- Etereum blockchain
- Evento
- Eventos
- ejemplo
- Intercambio
- esperado
- experience
- Feature
- Costes
- financiero
- Nombre
- Fijar
- Flash
- seguir
- encontrado
- función
- fondo
- fondos
- futuras
- GAS
- tarifas de gas
- Diezmos y Ofrendas
- gobierno
- Ahorrar
- es
- esta página
- Alta
- Destacado
- titulares
- Cómo
- HTTPS
- incentivar
- incluido
- Incluye
- aumente
- información
- intereses
- Interfaz
- cuestiones
- IT
- conocido
- Lead
- Biblioteca
- Líquido
- Liquidez
- proveedores de liquidez
- Lista
- Préstamos
- localmente
- cerrado
- LP
- LPs
- Mercado
- Match
- MEJOR DE TU
- habiertos
- oráculo
- Otro
- plataforma
- alberca
- Albercas
- industria
- la prevención
- precio
- propuesta
- proporcionar
- proporciona un
- público
- razones
- reducir
- Informes
- RESTO
- Resultados
- devoluciones
- una estrategia SEO para aparecer en las búsquedas de Google.
- Riesgo
- EN LINEA
- Servicios
- set
- establecimiento
- En Corto
- importante
- similares
- chica
- So
- solidez
- Alguien
- algo
- velocidad
- pasar
- Estado
- Posicionamiento
- STORAGE
- comercial
- Soportado
- Superficie
- te
- test
- A través de esta formación, el personal docente y administrativo de escuelas y universidades estará preparado para manejar los recursos disponibles que derivan de la diversidad cultural de sus estudiantes. Además, un mejor y mayor entendimiento sobre estas diferencias y similitudes culturales permitirá alcanzar los objetivos de inclusión previstos.
- a lo largo de
- equipo
- ficha
- Tokens
- parte superior
- Seguimiento
- transaccional
- Transacciones
- Confía en
- Actualizar
- Actualizaciones
- UPS
- usuarios
- propuesta de
- Ver
- lista blanca
- QUIENES
- dentro de
- sin
- Actividades:
- valor
- cero